Commit fe842ff4 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

softpll.c: aligns the aux channel with the reference clock when locking is…

softpll.c: aligns the aux channel with the reference clock when locking is completed, little optimization in dmpll_irq()
parent 4df15ce2
......@@ -14,6 +14,7 @@ White Rabbit Softcore PLL (SoftPLL)
#include <hw/softpll_regs.h>
#include "gpio.h"
#include "softpll.h"
/* Bit size of phase tags generated by the DMTDs. Used to sign-extend the tags. */
#define TAG_BITS 20
......@@ -245,7 +246,7 @@ void main_init(struct spll_dmpll_state *s)
}
static struct spll_helper_state helper;
static struct spll_dmpll_state main, aux;
static struct spll_dmpll_state main, auxpll;
static volatile int irq_cnt = 0;
#define HELPER_PERIOD_BITS 8
......@@ -291,12 +292,12 @@ static inline void helper_irq(struct spll_helper_state *hpll, int tag_ref)
if(ld_update(&hpll->ld_phase, err))
{
SPLL->CSR = SPLL_CSR_TAG_EN_W(CHAN_FB | CHAN_REF);
SPLL->CSR |= SPLL_CSR_TAG_EN_W(CHAN_FB | CHAN_REF);
};
}
}
void dmpll_irq(struct spll_dmpll_state *dmpll, int tag_ref, int tag_fb)
void dmpll_irq(struct spll_dmpll_state *dmpll, int tag_ref, int tag_fb, volatile uint32_t *dac)
{
int err, tmp, y, fb_ready;
......@@ -331,7 +332,7 @@ void dmpll_irq(struct spll_dmpll_state *dmpll, int tag_ref, int tag_fb)
err = dmpll->period_ref - dmpll->period_fb;
y = pi_update(&dmpll->pi_freq, err);
SPLL->DAC_DMPLL = y;
*dac = y;
if(ld_update(&dmpll->ld_freq, err))
{
/* frequency has been stable for quite a while? switch to phase branch */
......@@ -354,12 +355,12 @@ void dmpll_irq(struct spll_dmpll_state *dmpll, int tag_ref, int tag_fb)
if(fb_ready)
{
while (tag_ref > 16384 ) tag_ref-=16384; /* fixme */
while (tag_fb > 16384 ) tag_fb-=16384;
tag_ref &= 0x3fff; //while (tag_ref > 16384 ) tag_ref-=16384; /* fixme */
tag_fb &= 0x3fff; //while (tag_fb > 16384 ) tag_fb-=16384;
err = tag_ref - tag_fb;
y = pi_update(&dmpll->pi_phase, err);
SPLL->DAC_DMPLL = y;
*dac = y;
ld_update(&dmpll->ld_phase, err);
if(dmpll->setpoint < dmpll->phase_shift)
dmpll->setpoint++;
......@@ -370,11 +371,14 @@ void dmpll_irq(struct spll_dmpll_state *dmpll, int tag_ref, int tag_fb)
}
int aux_en = 0;
void _irq_entry()
{
volatile uint32_t csr;
int tag_ref = -1;
int tag_fb = -1;
int tag_aux = -1;
irq_cnt ++;
......@@ -385,12 +389,43 @@ void _irq_entry()
if(csr & READY_FB)
tag_fb = SPLL->TAG_FB;
if(csr & READY_AUX)
tag_aux = SPLL->TAG_AUX;
helper_irq(&helper, tag_ref);
if(helper.ld_phase.locked)
dmpll_irq(&main, tag_ref, tag_fb);
{
dmpll_irq(&main, tag_ref, tag_fb, &SPLL->DAC_DMPLL);
/* Aux channel - i.e. the oscillator on the FMC card */
if((csr & SPLL_CSR_AUX_EN) )
{
if(!(csr & CHAN_AUX))
{
auxpll.ld_phase.locked = 0;
auxpll.phase_shift = main.phase_shift;
auxpll.setpoint =0;
auxpll.freq_mode = 1;
pi_init(&auxpll.pi_freq);
ld_init(&auxpll.ld_freq);
//aux_en = 1;
}
dmpll_irq(&auxpll, tag_ref, tag_aux, &SPLL->DAC_AUX);
SPLL->CSR = SPLL_CSR_TAG_EN_W(CHAN_FB | CHAN_REF | CHAN_AUX) | (auxpll.ld_phase.locked ? SPLL_CSR_AUX_LOCK : 0);
} else {
auxpll.ld_phase.locked = 0;
auxpll.phase_shift = main.phase_shift;
auxpll.setpoint =0;
SPLL->CSR = SPLL_CSR_TAG_EN_W(CHAN_FB | CHAN_REF);
// aux_en = 0;
}
}
clear_irq();
}
......@@ -404,6 +439,7 @@ void softpll_enable()
helper_init(&helper);
main_init(&main);
main_init(&auxpll);
SPLL->DAC_HPLL = 0;
SPLL->DEGLITCH_THR = 2000;
......@@ -412,28 +448,46 @@ void softpll_enable()
SPLL->EIC_IER = 1;
enable_irq();
TRACE_DEV("[softpll]: enabled\n");
TRACE_DEV("*********************** [softpll]: enabled\n");
// softpll_check_lock();
prev_lck = 0;
}
void test_aux()
{
for(;;)
{ SPLL->DAC_AUX = 0;
timer_delay(100);
SPLL->DAC_AUX = 65500;
timer_delay(100);
mprintf(".");
}
}
int softpll_check_lock()
{
static int prev_lck = 0;
int lck = !helper.freq_mode && helper.ld_phase.locked && !main.freq_mode && main.ld_phase.locked;
if(!lck)
TRACE_DEV("%d%d%d%d\n", helper.freq_mode, helper.ld_phase.locked, main.freq_mode, main.ld_phase.locked) ;
// if(!lck)
TRACE_DEV("%d %d%d%d%d%d%d\n", irq_cnt, helper.freq_mode, helper.ld_phase.locked, main.freq_mode, main.ld_phase.locked, auxpll.freq_mode, auxpll.ld_phase.locked) ;
if(lck && !prev_lck) {
TRACE_DEV("[softpll]: got lock\n");
}else if (!lck && prev_lck)
TRACE_DEV("[softpll]: lost lock\n");
prev_lck = lck;
return lck;
}
int softpll_get_aux_status()
{
return ((SPLL->CSR & SPLL_CSR_AUX_EN) ? SOFTPLL_AUX_ENABLED: 0) | (auxpll.ld_phase.locked ? SOFTPLL_AUX_LOCKED: 0);
}
int softpll_busy(int channel)
{
// mprintf("busy?");
......@@ -443,6 +497,7 @@ int softpll_busy(int channel)
void softpll_set_phase( int ps)
{
main.phase_shift = (-(int32_t) ((int64_t)ps * 16384LL / 8000LL)) << SETPOINT_FRACBITS;
auxpll.phase_shift = (-(int32_t) ((int64_t)ps * 16384LL / 8000LL)) << SETPOINT_FRACBITS;
}
void softpll_disable()
......
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