Commit 8fefa391 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

rt: external 10MHz reference support for softpll, updated SPLL register layout

parent e466e7f5
......@@ -22,14 +22,29 @@ static volatile struct SPLL_WB *SPLL = (volatile struct SPLL_WB *) BASE_SOFTPLL;
#include "spll_helper.h"
#include "spll_main.h"
#include "spll_ptracker.h"
#include "spll_external.h"
#define CHAN_TCXO 4
#define CHAN_EXT 5
static volatile struct spll_helper_state helper;
static volatile struct spll_external_state extpll;
static volatile struct spll_main_state mpll;
static volatile struct spll_ptracker_state ptrackers[MAX_PTRACKERS];
#define MODE_GRAND_MASTER 0
#define MODE_FREERUNNING_MASTER 1
#define MODE_SLAVE 2
static volatile int mode = MODE_GRAND_MASTER;
static volatile int helper_locked = 0;
void _irq_entry()
{
volatile uint32_t trr;
int src = -1, tag;
int i;
if(! (SPLL->CSR & SPLL_TRR_CSR_EMPTY))
{
......@@ -37,27 +52,64 @@ void _irq_entry()
src = SPLL_TRR_R0_CHAN_ID_R(trr);
tag = SPLL_TRR_R0_VALUE_R(trr);
helper_update(&helper, tag, src);
mpll_update(&mpll, tag, src);
switch(mode) {
case MODE_GRAND_MASTER:
external_update(&extpll, tag, src);
break;
};
// helper_update(&helper, tag, src);
/* if(helper.ld.locked && !helper_locked)
{
for(i=0;i<n_chan_ref; i++)
ptracker_init(&ptrackers[i], CHAN_TCXO, i, 512);
}
if(helper.ld.locked)
{
for(i=0;i<n_chan_ref; i++)
ptracker_update(&ptrackers[i], tag, src);
} else {
for(i=0;i<n_chan_ref; i++)
ptrackers[i].ready = 0;
}
*/
/*
if(helper.ld.locked && !helper_locked)
{
if(!master_mode) mpll_start(&mpll);
helper_locked= 1;
}
if(helper.ld.locked && !master_mode)
{
mpll_update(&mpll, tag, src);
}*/
}
irq_count++;
clear_irq();
irq_count++;
clear_irq();
}
void spll_init()
void spll_init(int _master_mode, int ref_channel)
{
volatile int dummy;
disable_irq();
n_chan_ref = SPLL_CSR_N_REF_R(SPLL->CSR);
n_chan_out = SPLL_CSR_N_OUT_R(SPLL->CSR);
TRACE("SPLL_Init: %d ref channels, %d out channels\n", n_chan_ref, n_chan_out);
helper_locked = 0;
// master_mode = _master_mode;
TRACE("SPLL_Init: %s mode, %d ref channels, %d out channels\n", _master_mode ? "Master" : "Slave", n_chan_ref, n_chan_out);
SPLL->DAC_HPLL = 0;
timer_delay(100000);
timer_delay(100000);
SPLL->CSR= 0 ;
SPLL->OCER = 0;
SPLL->RCER = 0;
......@@ -67,44 +119,23 @@ void spll_init()
while(! (SPLL->TRR_CSR & SPLL_TRR_CSR_EMPTY)) dummy = SPLL->TRR_R0;
dummy = SPLL->PER_HPLL;
SPLL->EIC_IER = 1;
}
int spll_check_lock()
{
return helper.ld.locked ? 1 : 0;
}
#define CHAN_TCXO 8
void spll_test()
{
int i = 0;
volatile int dummy;
// helper_init(&helper, master_mode ? CHAN_TCXO : ref_channel);
// if(!master_mode)
// mpll_init(&mpll, ref_channel, CHAN_TCXO);
// helper_start(&helper);
external_init(&extpll, CHAN_EXT);
external_start(&extpll, 1);
spll_init();
helper_init(&helper, 0);
helper_start(&helper);
mpll_init(&mpll, 0, CHAN_TCXO);
enable_irq();
// mpll_init(&mpll, 0, CHAN_TCXO);
while(!helper.ld.locked) ;//TRACE("%d\n", helper.phase.ld.locked);
TRACE("Helper locked, starting main\n");
mpll_start(&mpll);
for(;;) mprintf("irqcount %d t %d lock %d\n", irq_count, eee, extpll.ld.locked);
}
/*
#define CHAN_AUX 7
#define CHAN_EXT 6
int spll_gm_measure_ext_phase()
int spll_check_lock()
{
SPLL->CSR = 0;
SPLL->DCCR = SPLL_DCCR_GATE_DIV_W(25);
SPLL->RCGER = (1<<CHAN_AUX);
SPLL->RCGER = (1<<CHAN_EXT);
return 0;
// return helper.ld.locked & (mpll.ld.locked || master_mode) ? 1 : 0;
}
*/
\ No newline at end of file
......@@ -34,6 +34,11 @@ typedef struct {
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. */
......@@ -113,6 +118,24 @@ static void ld_init(spll_lock_det_t *ld)
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 {
lp->y_d = lp->y_d + ((lp->alpha * (x - lp->y_d)) >> 16);
return lp->y_d;
}
}
/* Enables/disables DDMTD tag generation on a given (channel).
......
......@@ -22,6 +22,7 @@ integral/proportional gains on the response of the system.
#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 */
......
......@@ -31,7 +31,7 @@ WARNING: These parameters must be in sync with the generics of the HDL instantia
#define MAX_CHAN_OUT 1
/* Max. allowed number of phase trackers */
#define MAX_TRACKERS 6
#define MAX_PTRACKERS 6
/* Number of bits of the DAC(s) driving the oscillator(s). Must be the same for
all the outputs. */
......
#define BB_ERROR_BITS 16
struct spll_external_state {
int ref_src;
int sample_n;
int ph_err_offset, ph_err_cur, ph_err_d0, ph_raw_d0;
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)
{
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;
pi_init(&s->pi);
ld_init(&s->ld);
lowpass_init(&s->lp_short, 4000);
lowpass_init(&s->lp_long, 1000);
}
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;
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);
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, int align_pps)
{
s->sample_n = 0;
SPLL->ECCR = SPLL_ECCR_EXT_EN;
mprintf("ExtStartup\n");
spll_debug(DBG_EVENT | DBG_EXT, DBG_EVT_START, 1);
if(align_pps)
{
SPLL->ECCR |= SPLL_ECCR_ALIGN_EN;
while (! (SPLL->ECCR & SPLL_ECCR_ALIGN_DONE));
}
}
......@@ -3,7 +3,7 @@
* File : softpll_regs.h
* Author : auto-generated by wbgen2 from spll_wb_slave.wb
* Created : Wed Mar 7 11:09:46 2012
* Created : Thu Apr 12 14:15:28 2012
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE spll_wb_slave.wb
......@@ -14,8 +14,6 @@
#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
......@@ -54,17 +52,31 @@
/* definitions for field: Enable Period Measurement in reg: SPLL Control/Status Register */
#define SPLL_CSR_PER_EN WBGEN2_GEN_MASK(19, 1)
/* definitions for register: External Clock Control Register */
/* definitions for field: Enable External Clock BB Detector in reg: External Clock Control Register */
#define SPLL_ECCR_EXT_EN WBGEN2_GEN_MASK(0, 1)
/* definitions for field: External Clock Input Available in reg: External Clock Control Register */
#define SPLL_ECCR_EXT_SUPPORTED WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Enable PPS/phase alignment in reg: External Clock Control Register */
#define SPLL_ECCR_ALIGN_EN WBGEN2_GEN_MASK(2, 1)
/* definitions for field: PPS/phase alignment done in reg: External Clock Control Register */
#define SPLL_ECCR_ALIGN_DONE WBGEN2_GEN_MASK(3, 1)
/* definitions for register: DMTD Clock Control Register */
/* definitions for field: DMTD Clock Gate Divider in reg: DMTD Clock Control Register */
/* definitions for field: DMTD Clock Undersampling Divider in reg: DMTD Clock Control Register */
#define SPLL_DCCR_GATE_DIV_MASK WBGEN2_GEN_MASK(0, 6)
#define SPLL_DCCR_GATE_DIV_SHIFT 0
#define SPLL_DCCR_GATE_DIV_W(value) WBGEN2_GEN_WRITE(value, 0, 6)
#define SPLL_DCCR_GATE_DIV_R(reg) WBGEN2_GEN_READ(reg, 0, 6)
/* definitions for register: Reference Channel Gating Enable Register */
/* definitions for register: Reference Channel Undersampling Enable Register */
/* definitions for field: Reference Channel Gating Enable in reg: Reference Channel Gating Enable Register */
/* definitions for field: Reference Channel Undersampling Enable in reg: Reference Channel Undersampling Enable Register */
#define SPLL_RCGER_GATE_SEL_MASK WBGEN2_GEN_MASK(0, 32)
#define SPLL_RCGER_GATE_SEL_SHIFT 0
#define SPLL_RCGER_GATE_SEL_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
......@@ -206,28 +218,30 @@
PACKED struct SPLL_WB {
/* [0x0]: REG SPLL Control/Status Register */
uint32_t CSR;
/* [0x4]: REG DMTD Clock Control Register */
/* [0x4]: REG External Clock Control Register */
uint32_t ECCR;
/* [0x8]: REG DMTD Clock Control Register */
uint32_t DCCR;
/* [0x8]: REG Reference Channel Gating Enable Register */
/* [0xc]: REG Reference Channel Undersampling Enable Register */
uint32_t RCGER;
/* [0xc]: REG Output Channel Control Register */
/* [0x10]: REG Output Channel Control Register */
uint32_t OCCR;
/* [0x10]: REG Reference Channel Enable Register */
/* [0x14]: REG Reference Channel Enable Register */
uint32_t RCER;
/* [0x14]: REG Output Channel Enable Register */
/* [0x18]: REG Output Channel Enable Register */
uint32_t OCER;
/* [0x18]: REG HPLL Period Error */
/* [0x1c]: REG HPLL Period Error */
uint32_t PER_HPLL;
/* [0x1c]: REG Helper DAC Output */
/* [0x20]: REG Helper DAC Output */
uint32_t DAC_HPLL;
/* [0x20]: REG Main DAC Output */
/* [0x24]: REG Main DAC Output */
uint32_t DAC_MAIN;
/* [0x24]: REG Deglitcher threshold */
/* [0x28]: REG Deglitcher threshold */
uint32_t DEGLITCH_THR;
/* [0x28]: REG Debug FIFO Register - SPLL side */
/* [0x2c]: REG Debug FIFO Register - SPLL side */
uint32_t DFR_SPLL;
/* padding to: 16 words */
uint32_t __padding_0[5];
uint32_t __padding_0[4];
/* [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