From 08ff71ccf76110bc7c9df694bcf9d51f14489c76 Mon Sep 17 00:00:00 2001 From: Grzegorz Daniluk <g.daniluk@elproma.com.pl> Date: Thu, 26 Jul 2012 14:58:07 +0200 Subject: [PATCH] SoftPLL moved to ptp-noposix repo --- Makefile | 8 +- ptp-noposix | 2 +- softpll/softpll.mk | 1 - softpll/softpll_ng.c | 595 ---------------------------------------- softpll/softpll_ng.h | 37 --- softpll/spll_common.h | 170 ------------ softpll/spll_debug.h | 50 ---- softpll/spll_external.h | 214 --------------- softpll/spll_helper.h | 113 -------- softpll/spll_main.h | 218 --------------- softpll/spll_ptracker.h | 95 ------- 11 files changed, 5 insertions(+), 1498 deletions(-) delete mode 100644 softpll/softpll.mk delete mode 100644 softpll/softpll_ng.c delete mode 100644 softpll/softpll_ng.h delete mode 100644 softpll/spll_common.h delete mode 100644 softpll/spll_debug.h delete mode 100644 softpll/spll_external.h delete mode 100644 softpll/spll_helper.h delete mode 100644 softpll/spll_main.h delete mode 100644 softpll/spll_ptracker.h diff --git a/Makefile b/Makefile index 3d6c998..31a1cfc 100644 --- a/Makefile +++ b/Makefile @@ -56,7 +56,7 @@ OBJS_WRC = wrc_main.o \ PTP_NOPOSIX = ptp-noposix -INCLUDE_DIRS = -I$(PTP_NOPOSIX)/wrsw_hal -I$(PTP_NOPOSIX)/libptpnetif -Isoftpll -Iinclude +INCLUDE_DIRS = -I$(PTP_NOPOSIX)/wrsw_hal -I$(PTP_NOPOSIX)/libptpnetif -Isoftpll -I$(PTP_NOPOSIX)/softpll -Iinclude CFLAGS_EB = -DWITH_ETHERBONE=$(WITH_ETHERBONE) @@ -78,7 +78,8 @@ OBJS_PTPD = $(PTP_NOPOSIX)/PTPWRd/arith.o \ $(PTP_NOPOSIX)/PTPWRd/wr_protocol.o \ $(PTP_NOPOSIX)/libposix/freestanding-startup.o \ $(PTP_NOPOSIX)/libposix/freestanding-wrapper.o \ - $(PTP_NOPOSIX)/libposix/net.o + $(PTP_NOPOSIX)/libposix/net.o \ + $(PTP_NOPOSIX)/softpll/softpll_ng.o CFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled LDFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled -nostdlib -T arch/lm32/ram.ld @@ -89,7 +90,6 @@ include shell/shell.mk include tests/tests.mk include lib/lib.mk include sockitowm/sockitowm.mk -include softpll/softpll.mk include dev/dev.mk CC=$(CROSS_COMPILE)gcc @@ -125,4 +125,4 @@ clean: ${CC} $(CFLAGS) $(PTPD_CFLAGS) $(INCLUDE_DIR) $(LIB_DIR) -c $^ -o $@ tools: - make -C tools \ No newline at end of file + make -C tools diff --git a/ptp-noposix b/ptp-noposix index 256f803..b426591 160000 --- a/ptp-noposix +++ b/ptp-noposix @@ -1 +1 @@ -Subproject commit 256f803b8bcf671383ba5dd6a6f8d8c433727296 +Subproject commit b426591a40158a0f039e02716ff8f9aa95973271 diff --git a/softpll/softpll.mk b/softpll/softpll.mk deleted file mode 100644 index 2536eff..0000000 --- a/softpll/softpll.mk +++ /dev/null @@ -1 +0,0 @@ -OBJS_SOFTPLL = softpll/softpll_ng.o diff --git a/softpll/softpll_ng.c b/softpll/softpll_ng.c deleted file mode 100644 index eab47b8..0000000 --- a/softpll/softpll_ng.c +++ /dev/null @@ -1,595 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> - -#include "board.h" -#include "timer.h" -#include "trace.h" -#include "hw/softpll_regs.h" -#include "hw/pps_gen_regs.h" - -#include "softpll_ng.h" - -#include "irq.h" - -volatile int irq_count = 0; - -static volatile struct SPLL_WB *SPLL; -static volatile struct PPSG_WB *PPSG; - -#define TRACE(...) TRACE_DEV(__VA_ARGS__) - -/* The includes below contain code (not only declarations) to enable the compiler - to inline functions where necessary and save some CPU cycles */ - -#include "spll_defs.h" -#include "spll_common.h" -#include "spll_debug.h" -#include "spll_helper.h" -#include "spll_main.h" -#include "spll_ptracker.h" -#include "spll_external.h" - -#define SEQ_START_EXT 1 -#define SEQ_WAIT_EXT 2 -#define SEQ_START_HELPER 3 -#define SEQ_WAIT_HELPER 4 -#define SEQ_START_MAIN 5 -#define SEQ_WAIT_MAIN 6 -#define SEQ_DISABLED 7 -#define SEQ_READY 8 -#define SEQ_CLEAR_DACS 9 -#define SEQ_WAIT_CLEAR_DACS 10 - -#define AUX_DISABLED 1 -#define AUX_LOCK_PLL 2 -#define AUX_ALIGN_PHASE 3 -#define AUX_READY 4 - -struct spll_aux_state { - int state; - int32_t phase_target; -}; - -struct softpll_state { - int mode; - int seq_state; - int helper_locked; - int dac_timeout; - int default_dac_main; - int delock_count; - int32_t mpll_shift_ps; - - struct spll_helper_state helper; - struct spll_external_state ext; - struct spll_main_state mpll; - struct spll_main_state aux[MAX_CHAN_AUX]; - struct spll_aux_state aux_fsm[MAX_CHAN_AUX]; - struct spll_ptracker_state ptrackers[MAX_PTRACKERS]; -}; - -static volatile struct softpll_state softpll; - -static volatile int ptracker_mask = 0; /* fixme: should be done by spll_init() but spll_init is called to switch modes (and we won't like messing around with ptrackers there) */ - -void _irq_entry() -{ - volatile uint32_t trr; - int src = -1, tag, i; - struct softpll_state *s = (struct softpll_state *) &softpll; - -/* check if there are more tags in the FIFO */ - -// softpll.seq_state = SEQ_WAIT_CLEAR_DACS; - - while(! (SPLL->TRR_CSR & SPLL_TRR_CSR_EMPTY)) - { - trr = SPLL->TRR_R0; - src = SPLL_TRR_R0_CHAN_ID_R(trr); - tag = SPLL_TRR_R0_VALUE_R(trr); - - - 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 > TICS_PER_SECOND/20) - softpll.seq_state = (softpll.mode == SPLL_MODE_GRAND_MASTER ? SEQ_START_EXT : SEQ_START_HELPER); - break; - - case SEQ_DISABLED: - break; - - case SEQ_START_EXT: - external_update((struct spll_external_state *) &s->ext, tag, src); - external_start((struct spll_external_state *) &s->ext); - softpll.seq_state = SEQ_WAIT_EXT; - break; - - case SEQ_WAIT_EXT: - if(external_locked((struct spll_external_state *) &s->ext)) - softpll.seq_state = SEQ_START_HELPER; - break; - - case SEQ_START_HELPER: - softpll.helper_locked = 0; - helper_start((struct spll_helper_state *) &s->helper); - softpll.seq_state = SEQ_WAIT_HELPER; - break; - - case SEQ_WAIT_HELPER: - if(softpll.helper.ld.locked && !softpll.helper_locked) - { - softpll.helper_locked = 1; - - if(softpll.mode == SPLL_MODE_SLAVE) - softpll.seq_state = SEQ_START_MAIN; - else { - for(i=0;i<n_chan_ref; i++) - if(ptracker_mask & (1<<i)) - ptracker_start((struct spll_ptracker_state *) &s->ptrackers[i]); - softpll.seq_state = SEQ_READY; - } - } - break; - - case SEQ_START_MAIN: - mpll_start((struct spll_main_state *) &s->mpll); - softpll.seq_state = SEQ_WAIT_MAIN; - break; - - case SEQ_WAIT_MAIN: - if(softpll.mpll.ld.locked) - { - softpll.seq_state = SEQ_READY; - - for(i=0;i<n_chan_ref; i++) - if(ptracker_mask & (1<<i)) - ptracker_start((struct spll_ptracker_state *) &s->ptrackers[i]); - } - break; - - case SEQ_READY: - if(!softpll.helper.ld.locked) - { -// SPLL->OCER = 0; -// SPLL->RCER = 0; - softpll.seq_state = SEQ_CLEAR_DACS; - softpll.delock_count++; - } else if (softpll.mode == SPLL_MODE_GRAND_MASTER && !external_locked((struct spll_external_state *) &s->ext)) - { -// SPLL->OCER = 0; -// SPLL->RCER = 0; -// SPLL->ECCR = 0; - softpll.seq_state = SEQ_START_EXT; - softpll.delock_count++; - } else if (softpll.mode == SPLL_MODE_SLAVE && !softpll.mpll.ld.locked) - { - softpll.seq_state = SEQ_CLEAR_DACS; - softpll.delock_count++; - }; - break; - }; - - - switch(softpll.seq_state) - { - case SEQ_WAIT_EXT: - external_update((struct spll_external_state *) &s->ext, tag, src); - break; - - case SEQ_WAIT_HELPER: - if(softpll.mode == SPLL_MODE_GRAND_MASTER) - external_update((struct spll_external_state *) &s->ext, tag, src); - helper_update((struct spll_helper_state *) &s->helper, tag, src); - break; - - case SEQ_WAIT_MAIN: - case SEQ_READY: - helper_update((struct spll_helper_state *) &s->helper, tag, src); - - if(softpll.mode == SPLL_MODE_GRAND_MASTER) - external_update((struct spll_external_state *) &s->ext, tag, src); - if(softpll.mode == SPLL_MODE_SLAVE) - { - mpll_update((struct spll_main_state *) &s->mpll, tag, src); - for(i=0;i<n_chan_out-1;i++) - mpll_update(&softpll.aux[i], tag, src); - } - - for(i=0;i<n_chan_ref; i++) - if(ptracker_mask & (1<<i)) - ptracker_update((struct spll_ptracker_state *) &s->ptrackers[i], tag, src); - - - break; - - - - } - - - } - - irq_count++; - clear_irq(); -} - -void spll_clear_dacs() -{ - SPLL->DAC_HPLL = 0; - SPLL->DAC_MAIN = 0; - timer_delay(10000); -} - -void spll_init(int mode, int slave_ref_channel, int align_pps) -{ - char mode_str[20]; - volatile int dummy; - int i; - - SPLL = (volatile struct SPLL_WB *) BASE_SOFTPLL; - PPSG = (volatile struct PPSG_WB *) BASE_PPS_GEN; - - disable_irq(); - - n_chan_ref = SPLL_CSR_N_REF_R(SPLL->CSR); - n_chan_out = SPLL_CSR_N_OUT_R(SPLL->CSR); - softpll.helper_locked = 0; - softpll.mode = mode; - softpll.default_dac_main = 0; - softpll.delock_count = 0; -// softpll.occr_prev = 0; - - SPLL->DAC_HPLL = 0; - SPLL->DAC_MAIN = 0; - - //timer_delay(100000); - - SPLL->CSR= 0 ; - SPLL->OCER = 0; - SPLL->RCER = 0; - SPLL->ECCR = 0; - SPLL->RCGER = 0; - SPLL->DCCR = 0; - SPLL->OCCR = 0; - - SPLL->DEGLITCH_THR = 1000; - - PPSG->ESCR = 0; - PPSG->CR = PPSG_CR_CNT_EN | PPSG_CR_CNT_RST | PPSG_CR_PWIDTH_W(100); - - switch(mode) - { - case SPLL_MODE_DISABLED: - strcpy(mode_str, "Disabled"); - softpll.seq_state = SEQ_DISABLED; - break; - - case SPLL_MODE_GRAND_MASTER: - strcpy(mode_str, "Grand Master"); - - softpll.seq_state = SEQ_CLEAR_DACS; - - external_init(&softpll.ext, n_chan_ref + n_chan_out, align_pps); - helper_init(&softpll.helper, n_chan_ref); - - mpll_init(&softpll.mpll, slave_ref_channel, n_chan_ref); - - for(i=0;i<n_chan_out-1;i++) - { - mpll_init(&softpll.aux[i], slave_ref_channel, n_chan_ref + i + 1); - softpll.aux_fsm[i].state = AUX_DISABLED; - } - - break; - - case SPLL_MODE_FREE_RUNNING_MASTER: - strcpy(mode_str, "Free-running Master"); - - softpll.seq_state = SEQ_CLEAR_DACS; - softpll.default_dac_main = 32000; - helper_init(&softpll.helper, n_chan_ref + slave_ref_channel); - - - mpll_init(&softpll.mpll, slave_ref_channel, n_chan_ref); - - for(i=0;i<n_chan_out-1;i++) - { - mpll_init(&softpll.aux[i], slave_ref_channel, n_chan_ref + i + 1); - softpll.aux_fsm[i].state = AUX_DISABLED; - } - - PPSG->ESCR = PPSG_ESCR_PPS_VALID | PPSG_ESCR_TM_VALID; - break; - - case SPLL_MODE_SLAVE: - strcpy(mode_str, "Slave"); - - softpll.seq_state = SEQ_CLEAR_DACS; - helper_init(&softpll.helper, slave_ref_channel); - mpll_init(&softpll.mpll, slave_ref_channel, n_chan_ref); - - for(i=0;i<n_chan_out-1;i++) - { - mpll_init(&softpll.aux[i], slave_ref_channel, n_chan_ref + i + 1); - softpll.aux_fsm[i].state = AUX_DISABLED; - } - - -// PPSG->ESCR = PPSG_ESCR_PPS_VALID | PPSG_ESCR_TM_VALID; - - break; - } - - for(i=0; i<n_chan_ref;i++) - ptracker_init(&softpll.ptrackers[i], n_chan_ref, i, PTRACKER_AVERAGE_SAMPLES); - - - TRACE("SPLL_Init: running as %s, %d ref channels, %d out channels\n", mode_str, n_chan_ref, n_chan_out); - - /* Purge tag buffer */ - while(! (SPLL->TRR_CSR & SPLL_TRR_CSR_EMPTY)) dummy = SPLL->TRR_R0; - dummy = SPLL->PER_HPLL; - - SPLL->EIC_IER = 1; - SPLL->OCER |= 1; - - enable_irq(); - -/* for(;;) - { - mprintf("irqcount %d Seqstate %d TmrTics %d m %d ast %d ", irq_count, softpll.seq_state, timer_get_tics(), softpll.mode, softpll.ext.realign_state); - for(i=0;i<n_chan_ref;i++) - { - int ph, ready; - ready = spll_read_ptracker(i, &ph); - mprintf("rp%d[%d]: %dps ", i, ready, ph); - } - mprintf("\n"); - }*/ - -} - -void spll_shutdown() -{ - SPLL->OCER = 0; - SPLL->RCER = 0; - SPLL->ECCR = 0; - SPLL->EIC_IDR = 1; -} - -void spll_start_channel(int channel) -{ - if (softpll.seq_state != SEQ_READY || !channel) - { - TRACE("Can't start channel %d, the PLL is not ready\n", channel); - return; - } - mpll_start(&softpll.aux[channel-1]); -} - -void spll_stop_channel(int channel) -{ - if(!channel) - return -1; - - mpll_stop(&softpll.aux[channel-1]); -} - -int spll_check_lock(int channel) -{ - if(!channel) - return (softpll.seq_state == SEQ_READY); - else - return (softpll.seq_state == SEQ_READY) && softpll.aux[channel-1].ld.locked; -} - -static int32_t from_picos(int32_t ps) -{ - return (int32_t) ((int64_t)ps * (int64_t)(1<<HPLL_N) / (int64_t)CLOCK_PERIOD_PICOSECONDS); -} - -static int32_t to_picos(int32_t units) -{ - return (int32_t) (((int64_t)units * (int64_t)CLOCK_PERIOD_PICOSECONDS) >> HPLL_N); -} - -/* Channel 0 = local PLL reference, 1...N = aux oscillators */ -static void set_phase_shift(int channel, int32_t value_picoseconds) -{ - volatile struct spll_main_state *st = (!channel ? &softpll.mpll : &softpll.aux[channel-1]); - int div = (DIVIDE_DMTD_CLOCKS_BY_2 ? 2: 1); - mpll_set_phase_shift(st, from_picos(value_picoseconds) / div); - softpll.mpll_shift_ps = value_picoseconds; -} - -void spll_set_phase_shift(int channel, int32_t value_picoseconds) -{ - int i; - if(channel == SPLL_ALL_CHANNELS) - { - spll_set_phase_shift(0, value_picoseconds); - for(i=0;i<n_chan_out-1;i++) - if(softpll.aux_fsm[i].state == AUX_READY) - set_phase_shift(i+1, value_picoseconds); - } else - set_phase_shift(channel, value_picoseconds); -} - -void spll_get_phase_shift(int channel, int32_t *current, int32_t *target) -{ - volatile struct spll_main_state *st = (!channel ? &softpll.mpll : &softpll.aux[channel-1]); - int div = (DIVIDE_DMTD_CLOCKS_BY_2 ? 2: 1); - if(current) *current = to_picos(st->phase_shift_current * div); - if(target) *target = to_picos(st->phase_shift_target * div); -} - -int spll_read_ptracker(int channel, int32_t *phase_ps, int *enabled) -{ - volatile struct spll_ptracker_state *st = &softpll.ptrackers[channel]; - int phase = st->phase_val; - if(phase < 0) phase += (1<<HPLL_N); - else if (phase >= (1<<HPLL_N)) phase -= (1<<HPLL_N); - - if(DIVIDE_DMTD_CLOCKS_BY_2) - { - phase <<= 1; - phase &= (1<<HPLL_N)-1; - } - - *phase_ps = to_picos(phase); - if(enabled) - *enabled = ptracker_mask & (1<<st->id_b) ? 1 : 0; - return st->ready; -} - -void spll_get_num_channels(int *n_ref, int *n_out) -{ - if(n_ref) *n_ref = n_chan_ref; - if(n_out) *n_out = n_chan_out; -} - -void spll_show_stats() -{ - if(softpll.mode > 0) - TRACE("Irq_count %d Sequencer_state %d mode %d Alignment_state %d HL%d EL%d ML%d HY=%d MY=%d DelCnt=%d\n", - irq_count, softpll.seq_state, softpll.mode, softpll.ext.realign_state, - softpll.helper.ld.locked, softpll.ext.ld.locked, softpll.mpll.ld.locked, - softpll.helper.pi.y, softpll.mpll.pi.y, softpll.delock_count); - -} - -int spll_shifter_busy(int channel) -{ - if(!channel) - return mpll_shifter_busy(&softpll.mpll); - else - return mpll_shifter_busy(&softpll.aux[channel-1]); -} - -void spll_enable_ptracker(int ref_channel, int enable) -{ - if(enable) { - spll_enable_tagger(ref_channel, 1); - ptracker_start((struct spll_ptracker_state *) &softpll.ptrackers[ref_channel]); - ptracker_mask |= (1<<ref_channel); - TRACE("Enabling ptracker channel: %d\n", ref_channel); - - } else { - ptracker_mask &= ~(1<<ref_channel); - if(ref_channel != softpll.mpll.id_ref) - spll_enable_tagger(ref_channel, 0); - TRACE("Disabling ptracker tagger: %d\n", ref_channel); - } -} - -int spll_get_delock_count() -{ - return softpll.delock_count; -} - -int spll_update_aux_clocks() -{ - uint32_t occr_aux_en = SPLL_OCCR_OUT_EN_R(SPLL->OCCR); - int i; - - for(i=0;i<n_chan_out-1;i++) - { - struct spll_aux_state *s = &softpll.aux_fsm[i]; - - if((! (occr_aux_en & (1<<(i+1))) && s->state != AUX_DISABLED)) - { - TRACE("[aux] disabled channel %d\n", i); - spll_stop_channel(i+1); - SPLL->OCCR &= ~ (SPLL_OCCR_OUT_LOCK_W((1<<(i+1)))); - s->state = AUX_DISABLED; - - } else switch(s->state) - { - case AUX_DISABLED: - if(occr_aux_en & (1<<(i+1)) && softpll.mpll.ld.locked) - { - TRACE("[aux] enabled channel %d\n", i); - s->state = AUX_LOCK_PLL; - spll_start_channel(i+1); - } - break; - - case AUX_LOCK_PLL: - if(softpll.aux[i].ld.locked) - { - TRACE("[aux] channel %d locked [aligning @ %d ps]\n", i, softpll.mpll_shift_ps); - set_phase_shift(i+1, softpll.mpll_shift_ps); - s->state = AUX_ALIGN_PHASE; - } - - break; - - case AUX_ALIGN_PHASE: - if(!mpll_shifter_busy(&softpll.aux[i])) - { - TRACE("[aux] channel %d phase aligned\n", i); - SPLL->OCCR |= SPLL_OCCR_OUT_LOCK_W((1<<(i+1))); - s->state = AUX_READY; - } - break; - - case AUX_READY: - if(!softpll.mpll.ld.locked || !softpll.aux[i].ld.locked) - { - TRACE("[aux] aux channel or mpll lost lock\n"); - SPLL->OCCR &= ~ (SPLL_OCCR_OUT_LOCK_W((1<<(i+1)))); - s->state = AUX_DISABLED; - } - break; - } - } -} - -int spll_get_aux_status(int channel) -{ - int rval = 0; - - if(softpll.aux_fsm[channel].state != AUX_DISABLED) - rval |= SPLL_AUX_ENABLED; - - if(softpll.aux_fsm[channel].state == AUX_READY) - rval |= SPLL_AUX_LOCKED; - - return rval; -} - -int spll_get_dac(int index) -{ - if(index < 0) - return softpll.helper.pi.y; - else if (index == 0) - return softpll.mpll.pi.y; - else if (index > 0) - return softpll.aux[index-1].pi.y; - return 0; -} - -void spll_set_dac(int index, int value) -{ - if(index < 0) - { - softpll.helper.pi.y = value; - SPLL->DAC_HPLL = value; - } - else { - SPLL->DAC_MAIN = SPLL_DAC_MAIN_DAC_SEL_W(index) | (value & 0xffff); - - if (index == 0) - softpll.mpll.pi.y = value; - else if (index > 0) - softpll.aux[index-1].pi.y = value; - } -} diff --git a/softpll/softpll_ng.h b/softpll/softpll_ng.h deleted file mode 100644 index 528b6c8..0000000 --- a/softpll/softpll_ng.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef __SOFTPLL_NG_H -#define __SOFTPLL_NG_H - -#include <stdio.h> -#include <stdlib.h> - -/* Modes */ -#define SPLL_MODE_GRAND_MASTER 1 -#define SPLL_MODE_FREE_RUNNING_MASTER 2 -#define SPLL_MODE_SLAVE 3 -#define SPLL_MODE_DISABLED 4 - -#define SPLL_ALL_CHANNELS 0xffff - -#define SPLL_AUX_ENABLED (1<<0) -#define SPLL_AUX_LOCKED (1<<1) - -void spll_init(int mode, int slave_ref_channel, int align_pps); -void spll_shutdown(); -void spll_start_channel(int channel); -void spll_stop_channel(int channel); -int spll_check_lock(int channel); -void spll_set_phase_shift(int channel, int32_t value_picoseconds); -void spll_get_phase_shift(int channel, int32_t *current, int32_t *target); -int spll_read_ptracker(int channel, int32_t *phase_ps, int *enabled); -void spll_get_num_channels(int *n_ref, int *n_out); -int spll_shifter_busy(int channel); -int spll_get_delock_count(); -int spll_update_aux_clocks(); -int spll_get_aux_status(int channel); - -void spll_set_dac(int index, int value); -int spll_get_dac(int index); - - -#endif - diff --git a/softpll/spll_common.h b/softpll/spll_common.h deleted file mode 100644 index ae1de91..0000000 --- a/softpll/spll_common.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - -White Rabbit Softcore PLL (SoftPLL) - common definitions - -Copyright (c) 2010 - 2012 CERN / BE-CO-HT (Tomasz WÅ‚ostowski) -Licensed under LGPL 2.1. - -spll_common.h - common data structures and functions - -*/ - - -/* Number of reference/output channels. Currently we support only one SoftPLL instantiation per project, - so these can remain static. */ -static int n_chan_ref, n_chan_out; - -/* PI regulator state */ -typedef struct { - int ki, kp; /* integral and proportional gains (1<<PI_FRACBITS == 1.0f) */ - int integrator; /* current integrator value */ - int bias; /* DC offset always added to the output */ - int anti_windup; /* when non-zero, anti-windup is enabled */ - int y_min; /* min/max output range, used by clapming and antiwindup algorithms */ - int y_max; - int x, y; /* Current input (x) and output value (y) */ -} spll_pi_t; - -/* lock detector state */ -typedef struct { - int lock_cnt; /* Lock sample counter */ - int lock_samples; /* Number of samples below the (threshold) to assume that we are locked */ - int delock_samples; /* Accumulated number of samples that causes the PLL go get out of lock. - delock_samples < lock_samples. */ - int threshold; /* Error threshold */ - int locked; /* Non-zero: we are locked */ -} spll_lock_det_t; - -/* simple, 1st-order lowpass filter */ -typedef struct { - int alpha; - int y_d; -} spll_lowpass_t; - -/* Processes a single sample (x) with PI control algorithm (pi). Returns the value (y) to - drive the actuator. */ -static inline int pi_update(spll_pi_t *pi, int x) -{ - int i_new, y; - pi->x = x; - i_new = pi->integrator + x; - - y = ((i_new * pi->ki + x * pi->kp) >> PI_FRACBITS) + pi->bias; - - /* clamping (output has to be in <y_min, y_max>) and anti-windup: - stop the integrator if the output is already out of range and the output - is going further away from y_min/y_max. */ - if(y < pi->y_min) - { - y = pi->y_min; - if((pi->anti_windup && (i_new > pi->integrator)) || !pi->anti_windup) - pi->integrator = i_new; - } else if (y > pi->y_max) { - y = pi->y_max; - if((pi->anti_windup && (i_new < pi->integrator)) || !pi->anti_windup) - pi->integrator = i_new; - } else /* No antiwindup/clamping? */ - pi->integrator = i_new; - - pi->y = y; - return y; -} - -/* initializes the PI controller state. Currently almost a stub. */ -static inline void pi_init(spll_pi_t *pi) -{ - pi->integrator = 0; -} - - - -/* Lock detector state machine. Takes an error sample (y) and checks if it's withing an acceptable range - (i.e. <-ld.threshold, ld.threshold>. If it has been inside the range for (ld.lock_samples) cyckes, the - FSM assumes the PLL is locked. - - Return value: - 0: PLL not locked - 1: PLL locked - -1: PLL just got out of lock - */ -static inline int ld_update(spll_lock_det_t *ld, int y) -{ - if (abs(y) <= ld->threshold) - { - if(ld->lock_cnt < ld->lock_samples) - ld->lock_cnt++; - - if(ld->lock_cnt == ld->lock_samples) - { - ld->locked = 1; - return 1; - } - } else { - if(ld->lock_cnt > ld->delock_samples) - ld->lock_cnt--; - - if(ld->lock_cnt == ld->delock_samples) - { - ld->lock_cnt= 0; - ld->locked = 0; - return -1; - } - } - return ld->locked; -} - -static void ld_init(spll_lock_det_t *ld) -{ - ld->locked = 0; - ld->lock_cnt = 0; -} - -static void lowpass_init(spll_lowpass_t *lp, int alpha) -{ - lp->y_d = 0x80000000; - lp->alpha = alpha; -} - -static int lowpass_update(spll_lowpass_t *lp, int x) -{ - if(lp->y_d == 0x80000000) - { - lp->y_d = x; - return x; - } else { - int scaled = (lp->alpha * (x - lp->y_d)) >> 15; - lp->y_d = lp->y_d + (scaled >> 1) + (scaled & 1); - return lp->y_d; - } -} - - -/* Enables/disables DDMTD tag generation on a given (channel). - -Channels (0 ... n_chan_ref - 1) are the reference channels (e.g. transceivers' RX clocks - or a local reference) - -Channels (n_chan_ref ... n_chan_out + n_chan_ref-1) are the output channels (local voltage - controlled oscillators). One output (usually the first one) is always used to drive the - oscillator which produces the reference clock for the transceiver. Other outputs can be - used to discipline external oscillators (e.g. on FMCs). - -*/ - -static void spll_enable_tagger(int channel, int enable) -{ - if(channel >= n_chan_ref) /* Output channel? */ - { - if(enable) - SPLL->OCER |= 1<< (channel - n_chan_ref); - else - SPLL->OCER &= ~ (1<< (channel - n_chan_ref)); - } else { /* Reference channel */ - if(enable) - SPLL->RCER |= 1<<channel; - else - SPLL->RCER &= ~ (1<<channel); - } - -// TRACE("%s: ch %d, OCER 0x%x, RCER 0x%x\n", __FUNCTION__, channel, SPLL->OCER, SPLL->RCER); -} diff --git a/softpll/spll_debug.h b/softpll/spll_debug.h deleted file mode 100644 index ffcb9a8..0000000 --- a/softpll/spll_debug.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - -White Rabbit Softcore PLL (SoftPLL) - common definitions - -Copyright (c) 2010 - 2012 CERN / BE-CO-HT (Tomasz WÅ‚ostowski) -Licensed under LGPL 2.1. - -spll_debug.h - debugging/diagnostic interface - -The so-called debug inteface is a large, interrupt-driven FIFO which passes -various realtime parameters (e.g. error value, tags, DAC drive) to an external -application where they are further analyzed. It's very useful for optimizing PI coefficients -and/or lock thresholds. - -The data is organized as a stream of samples, where each sample can store a number of parameters. -For example, a stream samples with Y and ERR parameters can be used to evaluate the impact of -integral/proportional gains on the response of the system. - -*/ - -#define DBG_Y 0 -#define DBG_ERR 1 -#define DBG_TAG 2 -#define DBG_REF 5 -#define DBG_PERIOD 3 -#define DBG_EVENT 4 -#define DBG_SAMPLE_ID 6 - -#define DBG_HELPER 0x20 /* Sample source: Helper PLL */ -#define DBG_EXT 0x40 /* Sample source: External Reference PLL */ -#define DBG_MAIN 0x0 /* ... : Main PLL */ - -#define DBG_EVT_START 1 /* PLL has just started */ -#define DBG_EVT_LOCKED 2 /* PLL has just become locked */ - - -/* Writes a parameter to the debug FIFO. - -value: value of the parameter. -what: type of the parameter and its' source. For example, - - DBG_ERR | DBG_HELPER means that (value) contains the phase error of the helper PLL. - - DBG_EVENT indicates an asynchronous event. (value) must contain the event type (DBG_EVT_xxx) - -last: when non-zero, indicates the last parameter in a sample. -*/ - -static inline void spll_debug(int what, int value, int last) -{ - SPLL->DFR_SPLL = (last ? 0x80000000 : 0) | (value & 0xffffff) | (what << 24); -} diff --git a/softpll/spll_external.h b/softpll/spll_external.h deleted file mode 100644 index e94c2f7..0000000 --- a/softpll/spll_external.h +++ /dev/null @@ -1,214 +0,0 @@ - -#include <timer.h> - -/* Number of bits of the BB phase detector error counter. Bit [BB_ERROR_BITS] is the wrap-around bit */ -#define BB_ERROR_BITS 16 - -/* Alignment FSM states */ - -/* 1st alignment stage, done before starting the ext channel PLL: alignment of the rising edge - of the external clock (10 MHz), with the rising edge of the local reference (62.5/125 MHz) - and the PPS signal. Because of non-integer ratio (6.25 or 12.5), the PLL must know which edges - shall be kept at phase==0. We align to the edge of the 10 MHz clock which comes right after the edge - of the PPS pulse (see drawing below): - -PLL reference (62.5 MHz) ____|^^^^|____|^^^^|____|^^^^|____|^^^^|____|^^^^|____|^^^^|____|^^^^|____|^^^^|____|^^^^|____|^^^^|____|^^^^|____| -External clock (10 MHz) ^^^^^^^^^|________________________|^^^^^^^^^^^^^^^^^^^^^^^^^|________________________|^^^^^^^^^^^^^^^^^^^^^^^^^|___ -External PPS ___________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - */ -#define REALIGN_STAGE1 1 -#define REALIGN_STAGE1_WAIT 2 - - -/* 2nd alignment stage, done after the ext channel PLL has locked. We make sure that the switch's internal PPS signal - is produced exactly on the edge of PLL reference in-phase with 10 MHz clock edge, which has come right after the PPS input - -PLL reference (62.5 MHz) ____|^^^^|____|^^^^|____|^^^^|____|^^^^|____|^^^^|____|^^^^|____|^^^^|____|^^^^|____|^^^^|____|^^^^|____|^^^^|____| -External clock (10 MHz) ^^^^^^^^^|________________________|^^^^^^^^^^^^^^^^^^^^^^^^^|________________________|^^^^^^^^^^^^^^^^^^^^^^^^^|___ -External PPS ___________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Internal PPS __________________________________|^^^^^^^^^|______________________________________________________________________ - ^ aligned clock edges and PPS -*/ - -#define REALIGN_STAGE2 3 -#define REALIGN_STAGE2_WAIT 4 - -/* Error state - PPS signal missing or of bad frequency */ -#define REALIGN_PPS_INVALID 5 - -/* Realignment is disabled (i.e. the switch inputs only the reference frequency, but not time) */ -#define REALIGN_DISABLED 6 - -/* Realignment done */ -#define REALIGN_DONE 7 - - -struct spll_external_state { - int ref_src; - int sample_n; - int ph_err_offset, ph_err_cur, ph_err_d0, ph_raw_d0; - int realign_clocks; - int realign_state; - int realign_timer; - spll_pi_t pi; - spll_lowpass_t lp_short, lp_long; - spll_lock_det_t ld; -}; - -static void external_init( struct spll_external_state *s, int ext_ref, int realign_clocks) -{ - - s->pi.y_min = 5; - s->pi.y_max = (1 << DAC_BITS) - 5; - s->pi.kp = (int)(300); - s->pi.ki = (int)(1); - - s->pi.anti_windup = 1; - s->pi.bias = 32768; - - /* Phase branch lock detection */ - s->ld.threshold = 250; - s->ld.lock_samples = 10000; - s->ld.delock_samples = 9990; - s->ref_src = ext_ref; - s->ph_err_cur = 0; - s->ph_err_d0 = 0; - s->ph_raw_d0 = 0; - - s->realign_clocks = realign_clocks; - s->realign_state = (realign_clocks ? REALIGN_STAGE1 : REALIGN_DISABLED); - - pi_init(&s->pi); - ld_init(&s->ld); - lowpass_init(&s->lp_short, 4000); - lowpass_init(&s->lp_long, 300); -} - -static inline void realign_fsm( struct spll_external_state *s) -{ - uint32_t eccr; - - - switch(s->realign_state) - { - case REALIGN_STAGE1: - SPLL->ECCR |= SPLL_ECCR_ALIGN_EN; - - s->realign_state = REALIGN_STAGE1_WAIT; - s->realign_timer = timer_get_tics(); - break; - - case REALIGN_STAGE1_WAIT: - - if(SPLL->ECCR & SPLL_ECCR_ALIGN_DONE) - s->realign_state = REALIGN_STAGE2; - else if (timer_get_tics() - s->realign_timer > 2*TICS_PER_SECOND) - { - SPLL->ECCR &= ~SPLL_ECCR_ALIGN_EN; - s->realign_state = REALIGN_PPS_INVALID; - } - break; - - case REALIGN_STAGE2: - if(s->ld.locked) - { - PPSG->CR = PPSG_CR_CNT_RST | PPSG_CR_CNT_EN; - PPSG->ADJ_UTCLO = 0; - PPSG->ADJ_UTCHI = 0; - PPSG->ADJ_NSEC = 0; - PPSG->ESCR = PPSG_ESCR_SYNC; - - s->realign_state = REALIGN_STAGE2_WAIT; - s->realign_timer = timer_get_tics(); - } - break; - - case REALIGN_STAGE2_WAIT: - if(PPSG->ESCR & PPSG_ESCR_SYNC) - { - PPSG->ESCR = PPSG_ESCR_PPS_VALID | PPSG_ESCR_TM_VALID; - s->realign_state = REALIGN_DONE; - } else if (timer_get_tics() - s->realign_timer > 2*TICS_PER_SECOND) - { - PPSG->ESCR = 0; - s->realign_state = REALIGN_PPS_INVALID; - } - break; - - case REALIGN_PPS_INVALID: - case REALIGN_DISABLED: - case REALIGN_DONE: - return ; - } -} - -static int external_update( struct spll_external_state *s, int tag, int source) -{ - int err, y, y2, yd, ylt; - - if(source == s->ref_src) - { - int wrap = tag & (1<<BB_ERROR_BITS) ? 1 : 0; - - realign_fsm(s); - - tag &= ((1<<BB_ERROR_BITS) - 1); - - - -// mprintf("err %d\n", tag); - if(wrap) - { - if(tag > s->ph_raw_d0) - s->ph_err_offset -= (1<<BB_ERROR_BITS); - else if(tag <= s->ph_raw_d0) - s->ph_err_offset += (1<<BB_ERROR_BITS); - } - - s->ph_raw_d0 = tag; - - err = (tag + s->ph_err_offset) - s->ph_err_d0; - s->ph_err_d0 = (tag + s->ph_err_offset); - - y = pi_update(&s->pi, err); - - y2 = lowpass_update(&s->lp_short, y); - ylt = lowpass_update(&s->lp_long, y); - - if(! (SPLL->ECCR & SPLL_ECCR_EXT_REF_PRESENT)) /* no reference? de-lock now */ - { - ld_init(&s->ld); - y2 = 32000; - } - - SPLL->DAC_MAIN = y2 & 0xffff; - - spll_debug(DBG_ERR | DBG_EXT, ylt, 0); - spll_debug(DBG_SAMPLE_ID | DBG_EXT, s->sample_n++, 0); - spll_debug(DBG_Y | DBG_EXT, y2, 1); - - if(ld_update(&s->ld, y2 - ylt)) - return SPLL_LOCKED; - } - return SPLL_LOCKING; -} - - -static void external_start( struct spll_external_state *s) -{ -// mprintf("ExtStartup\n"); - - SPLL->ECCR = 0; - - s->sample_n = 0; - s->realign_state = (s->realign_clocks ? REALIGN_STAGE1 : REALIGN_DISABLED); - - SPLL->ECCR = SPLL_ECCR_EXT_EN; - - spll_debug(DBG_EVENT | DBG_EXT, DBG_EVT_START, 1); -} - -static inline int external_locked( struct spll_external_state *s) -{ - return (s->ld.locked && (s->realign_clocks ? s->realign_state == REALIGN_DONE : 1)); -} diff --git a/softpll/spll_helper.h b/softpll/spll_helper.h deleted file mode 100644 index db8b7b4..0000000 --- a/softpll/spll_helper.h +++ /dev/null @@ -1,113 +0,0 @@ - -/* State of the Helper PLL producing a clock (clk_dmtd_i) which is - slightly offset in frequency from the recovered/reference clock (clk_rx_i or clk_ref_i), so the - Main PLL can use it to perform linear phase measurements. - */ - -#define SPLL_LOCKED 1 -#define SPLL_LOCKING 0 - -#define HELPER_TAG_WRAPAROUND 100000000 - -/* Maximum abs value of the phase error. If the error is bigger, it's clamped to this value. */ -#define HELPER_ERROR_CLAMP 150000 - -struct spll_helper_state { - int p_adder; /* anti wrap-around adder */ - int p_setpoint, tag_d0; - int ref_src; - int sample_n; - int delock_count; - spll_pi_t pi; - spll_lock_det_t ld; -}; - -static 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; - s->pi.kp = (int)(0.3 * 32.0 * 16.0);// / 2; - s->pi.ki = (int)(0.03 * 32.0 * 3.0);// / 2; - - s->pi.anti_windup = 1; - - /* Phase branch lock detection */ - s->ld.threshold = 200; - s->ld.lock_samples = 10000; - s->ld.delock_samples = 100; - s->ref_src = ref_channel; - s->delock_count = 0; -} - -static int helper_update(struct spll_helper_state *s, int tag, int source) -{ - int err, y; - - if(source == s->ref_src) - { - spll_debug(DBG_TAG | DBG_HELPER, tag, 0); - spll_debug(DBG_REF | DBG_HELPER, s->p_setpoint, 0); - - if(s->tag_d0 < 0) - { - s->p_setpoint = tag; - s->tag_d0 = tag; - - return SPLL_LOCKING; - } - - if(s->tag_d0 > tag) - s->p_adder += (1<<TAG_BITS); - - err = (tag + s->p_adder) - s->p_setpoint; - - if(HELPER_ERROR_CLAMP) - { - if(err < -HELPER_ERROR_CLAMP) err = -HELPER_ERROR_CLAMP; - if(err > HELPER_ERROR_CLAMP) err = HELPER_ERROR_CLAMP; - } - - if((tag + s->p_adder) > HELPER_TAG_WRAPAROUND && s->p_setpoint > HELPER_TAG_WRAPAROUND) - { - s->p_adder -= HELPER_TAG_WRAPAROUND; - s->p_setpoint -= HELPER_TAG_WRAPAROUND; - } - - s->p_setpoint += (1<<HPLL_N); - s->tag_d0 = tag; - - y = pi_update(&s->pi, err); - SPLL->DAC_HPLL = y; - - spll_debug(DBG_SAMPLE_ID | DBG_HELPER, s->sample_n++, 0); - spll_debug(DBG_Y | DBG_HELPER, y, 0); - spll_debug(DBG_ERR | DBG_HELPER, err, 1); - - if(ld_update(&s->ld, err)) - return SPLL_LOCKED; - } - return SPLL_LOCKING; -} - - - -static 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. */ - s->pi.bias = s->pi.y_max; - - s->p_setpoint = 0; - s->p_adder = 0; - s->sample_n = 0; - s->tag_d0 = -1; - - pi_init(&s->pi); - ld_init(&s->ld); - - spll_enable_tagger(s->ref_src, 1); - spll_debug(DBG_EVENT | DBG_HELPER, DBG_EVT_START, 1); -} - diff --git a/softpll/spll_main.h b/softpll/spll_main.h deleted file mode 100644 index a3c98f9..0000000 --- a/softpll/spll_main.h +++ /dev/null @@ -1,218 +0,0 @@ - -#define MPLL_TAG_WRAPAROUND 100000000 - -#define MATCH_NEXT_TAG 0 -#define MATCH_WAIT_REF 1 -#define MATCH_WAIT_OUT 2 - -#undef WITH_SEQUENCING - -/* State of the Main PLL */ -struct spll_main_state { - int state; - - spll_pi_t pi; - spll_lock_det_t ld; - - int adder_ref, adder_out, tag_ref, tag_out, tag_ref_d, tag_out_d; - - // tag sequencing stuff - uint32_t seq_ref, seq_out; - int match_state; - int match_seq; - - int phase_shift_target; - int phase_shift_current; - int id_ref, id_out; /* IDs of the reference and the output channel */ - int sample_n; - int delock_count; - int dac_index; -}; - - -static void mpll_init(struct spll_main_state *s, int id_ref, int id_out) -{ - /* Frequency branch PI controller */ - s->pi.y_min = 5; - s->pi.y_max = 65530; - s->pi.anti_windup = 1; - s->pi.bias = 65000; - s->pi.kp = 1100;// / 2; - s->pi.ki = 30;// / 2; - s->delock_count = 0; - - /* Freqency branch lock detection */ - s->ld.threshold = 1200; - s->ld.lock_samples = 1000; - s->ld.delock_samples = 100; - s->id_ref = id_ref; - s->id_out = id_out; - s->dac_index = id_out - n_chan_ref; - - pi_init(&s->pi); - ld_init(&s->ld); -} - -static void mpll_start(struct spll_main_state *s) -{ - s->adder_ref = s->adder_out = 0; - s->tag_ref = -1; - s->tag_out = -1; - s->tag_ref_d = -1; - s->tag_out_d = -1; - s->seq_ref = 0; - s->seq_out = 0; - s->match_state = MATCH_NEXT_TAG; - - s->phase_shift_target = 0; - s->phase_shift_current = 0; - s->sample_n= 0; - - pi_init(&s->pi); - ld_init(&s->ld); - - spll_enable_tagger(s->id_ref, 1); - spll_enable_tagger(s->id_out, 1); - spll_debug(DBG_EVENT | DBG_MAIN, DBG_EVT_START, 1); -} - -static void mpll_stop(struct spll_main_state *s) -{ - spll_enable_tagger(s->id_out, 0); -} - - -static int mpll_update(struct spll_main_state *s, int tag, int source) -{ - int err, y, tmp; - -#ifdef WITH_SEQUENCING - int new_ref = -1, new_out = -1; - - if(source == s->id_ref) - { - new_ref = tag; - s->seq_ref++; - } else if(source == s->id_out) { - new_out = tag; - s->seq_out++; - } - - - switch(s->match_state) - { - case MATCH_NEXT_TAG: - if(new_ref > 0 && s->seq_out < s->seq_ref) - { - s->tag_ref = new_ref; - s->match_seq = s->seq_ref; - s->match_state = MATCH_WAIT_OUT; - } - - if (new_out > 0 && s->seq_out > s->seq_ref) - { - s->tag_out = new_out; - s->match_seq = s->seq_out; - s->match_state = MATCH_WAIT_REF; - } - break; - case MATCH_WAIT_REF: - if(new_ref > 0 && s->seq_ref == s->match_seq) - { - s->match_state = MATCH_NEXT_TAG; - s->tag_ref = new_ref; - } - break; - - case MATCH_WAIT_OUT: - if(new_out > 0 && s->seq_out == s->match_seq) - { - s->match_state = MATCH_NEXT_TAG; - s->tag_out = new_out; - } - break; - } -#else - if(source == s->id_ref) - s->tag_ref = tag; - if(source == s->id_out) - s->tag_out = tag; - -#endif - - if(s->tag_ref >= 0 && s->tag_out >= 0) - { - - if(s->tag_ref_d >= 0 && s->tag_ref_d > s->tag_ref) - s->adder_ref += (1<<TAG_BITS); - if(s->tag_out_d >= 0 && s->tag_out_d > s->tag_out) - s->adder_out += (1<<TAG_BITS); - - s->tag_ref_d = s->tag_ref; - s->tag_out_d = s->tag_out; - - err = s->adder_ref + s->tag_ref - s->adder_out - s->tag_out; - -#ifndef WITH_SEQUENCING - - /* 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. - - Proper solution: tag sequence numbers */ - if(s->ld.locked) - { - err &= (1<<HPLL_N)-1; - if(err & (1<<(HPLL_N-1))) - err |= ~((1<<HPLL_N)-1); - } - - -#endif - - y = pi_update(&s->pi, err); - SPLL->DAC_MAIN = SPLL_DAC_MAIN_VALUE_W(y) | SPLL_DAC_MAIN_DAC_SEL_W(s->dac_index); - - 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); - - s->tag_out = -1; - s->tag_ref = -1; - - 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; - } - - if(s->ld.locked) - { - if(s->phase_shift_current < s->phase_shift_target) - { - s->phase_shift_current++; - s->adder_ref++; - } else if(s->phase_shift_current > s->phase_shift_target) { - s->phase_shift_current--; - s->adder_ref--; - } - } - if(ld_update(&s->ld, err)) - return SPLL_LOCKED; - - } - - return SPLL_LOCKING; -} - -static int mpll_set_phase_shift(struct spll_main_state *s, int desired_shift) -{ - s->phase_shift_target = desired_shift; -} - -static int mpll_shifter_busy(struct spll_main_state *s) -{ - return s->phase_shift_target != s->phase_shift_current; -} diff --git a/softpll/spll_ptracker.h b/softpll/spll_ptracker.h deleted file mode 100644 index 93744c4..0000000 --- a/softpll/spll_ptracker.h +++ /dev/null @@ -1,95 +0,0 @@ - -/* State of a Phase Tracker */ - -struct spll_ptracker_state { - int id_a, id_b; - int n_avg, acc, avg_count; - int phase_val, ready; - int tag_a, tag_b; - int sample_n; - int preserve_sign; -}; - - -static void ptracker_init(struct spll_ptracker_state *s, int id_a, int id_b, int num_avgs) -{ - s->tag_a = s->tag_b = -1; - - s->id_a = id_a; - s->id_b = id_b; - s->ready = 0; - s->n_avg = num_avgs; - s->acc = 0; - s->avg_count = 0; - s->sample_n= 0; - s->preserve_sign = 0; -} - -static void ptracker_start(struct spll_ptracker_state *s) -{ - s->tag_a = s->tag_b = -1; - s->ready = 0; - s->acc = 0; - s->avg_count = 0; - s->sample_n= 0; - s->preserve_sign = 0; - - spll_enable_tagger(s->id_a, 1); - spll_enable_tagger(s->id_b, 1); -} - -#define PTRACK_WRAP_LO (1<<(HPLL_N-2)) -#define PTRACK_WRAP_HI (3*(1<<(HPLL_N-2))) - -static int ptracker_update(struct spll_ptracker_state *s, int tag, int source) -{ - - if(source == s->id_a) - s->tag_a = tag; - if(source == s->id_b) - s->tag_b = tag; - - if(s->tag_a >= 0 && s->tag_b >= 0) - { - int delta = (s->tag_a - s->tag_b) & ((1<<HPLL_N) - 1); - - s->sample_n++; - - if(s->avg_count == 0) - { - - if(delta <= PTRACK_WRAP_LO) - s->preserve_sign = -1; - else if (delta >= PTRACK_WRAP_HI) - s->preserve_sign = 1; - else - s->preserve_sign = 0; - - s->avg_count++; - s->acc = delta; - } else { - - if(delta <= PTRACK_WRAP_LO && s->preserve_sign > 0) - s->acc += delta + (1<<HPLL_N); - else if (delta >= PTRACK_WRAP_HI && s->preserve_sign < 0) - s->acc += delta - (1<<HPLL_N); - else - s->acc += delta; - - s->avg_count++; - - if(s->avg_count == s->n_avg) - { - s->phase_val = s->acc / s->n_avg; - s->ready = 1; - s->acc = 0; - s->avg_count = 0; - } - - } - - s->tag_b = s->tag_a = -1; - } - - return SPLL_LOCKING; -} -- GitLab