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