Commit 2f457b20 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

softpll: tested DMTD external softpll with the switch. No holdover yet.

parent 24daa765
......@@ -153,7 +153,6 @@ int ad9516_set_output_divider(int output, int ratio, int phase_offset)
ad9516_write_reg(base + 1, div_ctl | (1<<7) | (phase_offset & 0xf));
} else {
uint8_t div_ctl = ad9516_read_reg(base + 1);
TRACE("DivCtl: %x\n", div_ctl);
ad9516_write_reg(base + 1, (div_ctl & (~(1<<7))) | (phase_offset & 0xf)); /* disable bypass bit */
ad9516_write_reg(base, (lcycles << 4) | hcycles);
}
......
......@@ -51,8 +51,6 @@ int spll_n_chan_ref, spll_n_chan_out;
#define AUX_ALIGN_PHASE 3
#define AUX_READY 4
#define TRACE_DEV pp_printf
struct spll_aux_state {
int seq_state;
int32_t phase_target;
......@@ -77,6 +75,21 @@ struct softpll_state {
struct spll_ptracker_state ptrackers[MAX_PTRACKERS];
};
static const struct stringlist_entry seq_states [] =
{
{ SEQ_START_EXT, "start-ext" },
{ SEQ_WAIT_EXT, "wait-ext" },
{ SEQ_START_HELPER, "start-helper" },
{ SEQ_WAIT_HELPER, "wait-helper" },
{ SEQ_START_MAIN, "start-main" },
{ SEQ_WAIT_MAIN, "wait-main" },
{ SEQ_DISABLED, "disabled" },
{ SEQ_READY, "ready" },
{ SEQ_CLEAR_DACS, "clear-dacs" },
{ SEQ_WAIT_CLEAR_DACS, "wait-clear-dacs" },
{ 0, NULL }
};
static volatile struct softpll_state softpll;
static volatile int ptracker_mask = 0;
......@@ -208,7 +221,6 @@ static inline void sequencing_fsm(struct softpll_state *s, int tag_value, int ta
case SEQ_READY:
{
//mprintf("SeqRdy\n");
if (s->mode == SPLL_MODE_GRAND_MASTER && !external_locked(&s->ext))
{
s->delock_count++;
......@@ -227,9 +239,6 @@ static inline void sequencing_fsm(struct softpll_state *s, int tag_value, int ta
static inline void update_loops(struct softpll_state *s, int tag_value, int tag_source)
{
// if(tag_source != 8)
// TRACE("%d %d\n", tag_value, tag_source);
helper_update(&s->helper, tag_value, tag_source);
......@@ -237,8 +246,7 @@ static inline void update_loops(struct softpll_state *s, int tag_value, int tag_
{
mpll_update(&s->mpll, tag_value, tag_source);
#if 0
if(s->seq_state == SEQ_READY)
if(s->seq_state == SEQ_READY)
{
if(s->mode == SPLL_MODE_SLAVE)
{
......@@ -249,7 +257,6 @@ static inline void update_loops(struct softpll_state *s, int tag_value, int tag_
update_ptrackers(s, tag_value, tag_source);
}
#endif
}
}
......@@ -473,15 +480,13 @@ void spll_get_num_channels(int *n_ref, int *n_out)
void spll_show_stats()
{
if (softpll.mode > 0)
TRACE_DEV("softpll: irq_count %d sequencer_state %d mode %d "
TRACE_DEV("softpll: irqs %d seq %s mode %d "
"alignment_state %d HL%d ML%d HY=%d MY=%d DelCnt=%d\n",
irq_count, softpll.seq_state, softpll.mode,
irq_count, stringlist_lookup(seq_states, softpll.seq_state), softpll.mode,
softpll.ext.align_state, softpll.helper.ld.locked, softpll.mpll.ld.locked,
softpll.helper.pi.y, softpll.mpll.pi.y,
softpll.delock_count);
TRACE_DEV("%d %d %d %d\n", softpll.mpll.tag_ref_d, softpll.mpll.tag_out_d, softpll.mpll.sample_n, softpll.mpll.tag_ref_d- softpll.mpll.tag_ref);
}
......@@ -649,7 +654,7 @@ void spll_update()
external_align_fsm(&softpll.ext);
break;
}
//spll_update_aux_clocks();
spll_update_aux_clocks();
}
int spll_measure_frequency(int osc)
......
......@@ -168,3 +168,14 @@ int biquad_update(spll_biquad_t *bq, int x)
return y;
}
const char *stringlist_lookup(const struct stringlist_entry *slist, int id)
{
int i;
for(i=0; slist[i].str; i++)
if(slist[i].id == id)
{
return slist[i].str;
}
return "<unknown>";
}
\ No newline at end of file
......@@ -24,6 +24,8 @@
#define SPLL_LOCKED 1
#define SPLL_LOCKING 0
/* Number of reference/output channels. We don't plan to have more than one
SoftPLL instantiation per project, so these can remain global. */
extern int spll_n_chan_ref, spll_n_chan_out;
......@@ -76,6 +78,11 @@ typedef struct {
int log[16];
} spll_lta_t;
struct stringlist_entry {
int id;
const char *str;
};
/* initializes the PI controller state. Currently almost a stub. */
void pi_init(spll_pi_t *pi);
......@@ -93,4 +100,7 @@ void spll_enable_tagger(int channel, int enable);
void biquad_init(spll_biquad_t *bq, const int *coefs, int shift);
int biquad_update(spll_biquad_t *bq, int x);
const char *stringlist_lookup(const struct stringlist_entry *slist, int id);
#endif // __SPLL_COMMON_H
......@@ -13,6 +13,9 @@
#include "spll_external.h"
#include "spll_debug.h"
#include "trace.h"
#include "irq.h"
#define ALIGN_STATE_EXT_OFF 0
#define ALIGN_STATE_START 1
#define ALIGN_STATE_INIT_CSYNC 2
......@@ -28,7 +31,8 @@
#define EXT_PERIOD_NS 100
#define EXT_FREQ_HZ 10000000
#define EXT_PPS_LATENCY_PS 30000
#define EXT_PPS_LATENCY_PS 30000 // fixme: make configurable
void external_init(volatile struct spll_external_state *s, int ext_ref,
int realign_clocks)
......@@ -39,8 +43,6 @@ void external_init(volatile struct spll_external_state *s, int ext_ref,
helper_init(s->helper, idx);
mpll_init(s->main, idx, spll_n_chan_ref);
TRACE("helper-idx %d main-idx %d\n", idx, spll_n_chan_ref);
s->align_state = ALIGN_STATE_EXT_OFF;
s->enabled = 0;
}
......@@ -48,28 +50,27 @@ void external_init(volatile struct spll_external_state *s, int ext_ref,
void external_start(struct spll_external_state *s)
{
helper_start(s->helper);
// mpll_start(s->main);
SPLL->ECCR = SPLL_ECCR_EXT_EN;
TRACE("ECCR %x\n", SPLL->ECCR);
// spll_debug (DBG_EVENT | DBG_EXT, DBG_EVT_START, 1);
s->align_state = ALIGN_STATE_START;
s->enabled = 1;
spll_debug (DBG_EVENT | DBG_EXT, DBG_EVT_START, 1);
}
int external_locked(struct spll_external_state *s)
{
if (!s->helper->ld.locked && s->main->ld.locked)
if (!s->helper->ld.locked || !s->main->ld.locked)
return 0;
switch(s->align_state)
{
case ALIGN_STATE_EXT_OFF:
case ALIGN_STATE_START:
case ALIGN_STATE_START_MAIN:
case ALIGN_STATE_INIT_CSYNC:
case ALIGN_STATE_WAIT_CSYNC:
case ALIGN_STATE_START_ALIGNMENT:
return 0;
default:
return 1;
......@@ -112,14 +113,10 @@ void external_align_fsm( struct spll_external_state *s )
s->align_state = ALIGN_STATE_START_MAIN;
}
break;
case ALIGN_STATE_START_MAIN:
SPLL->AL_CR = 2;
//TRACE("CIN %d CREF %d\n", SPLL->AL_CIN, SPLL->AL_CREF);
if(s->helper->ld.locked && s->main->ld.locked)
{
PPSG->CR = PPSG_CR_CNT_EN | PPSG_CR_PWIDTH_W(10);
......@@ -130,8 +127,6 @@ void external_align_fsm( struct spll_external_state *s )
}
break;
case ALIGN_STATE_INIT_CSYNC:
if (PPSG->ESCR & PPSG_ESCR_SYNC)
{
......@@ -195,6 +190,10 @@ void external_align_fsm( struct spll_external_state *s )
break;
case ALIGN_STATE_LOCKED:
if(!external_locked(s))
{
s->align_state = ALIGN_STATE_START;
}
break;
default:
......
......@@ -65,7 +65,6 @@ int helper_update(struct spll_helper_state *s, int tag,
err = HELPER_ERROR_CLAMP;
}
// err = biquad_update(&s->precomp, err);
if ((tag + s->p_adder) > HELPER_TAG_WRAPAROUND
&& s->p_setpoint > HELPER_TAG_WRAPAROUND) {
......
......@@ -27,7 +27,7 @@ void mpll_init(struct spll_main_state *s, int id_ref,
s->pi.y_min = 5;
s->pi.y_max = 65530;
s->pi.anti_windup = 1;
s->pi.bias = 30000; //65000;
s->pi.bias = 30000;
#if defined(CONFIG_WR_SWITCH)
s->pi.kp = 1100; // / 2;
s->pi.ki = 30; // / 2;
......@@ -75,9 +75,7 @@ void mpll_start(struct spll_main_state *s)
spll_enable_tagger(s->id_ref, 1);
spll_enable_tagger(s->id_out, 1);
//spll_debug(DBG_EVENT | DBG_MAIN, DBG_EVT_START, 1);
TRACE("MPLL_Start_Done [ref %d out %d]\n",s->id_ref, s->id_out);
//enable_irq();
spll_debug(DBG_EVENT | DBG_MAIN, DBG_EVT_START, 1);
}
void mpll_stop(struct spll_main_state *s)
......@@ -89,63 +87,34 @@ int mpll_update(struct spll_main_state *s, int tag, int source)
{
int err, y;
#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)
{
if(s->tag_ref_d >= 0 && s->tag_ref_d > s->tag_ref)
s->adder_ref += (1 << TAG_BITS);
s->tag_ref_d = s->tag_ref;
}
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)
if (s->tag_out >= 0)
{
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;
}
if (s->tag_ref >= 0 && s->tag_out >= 0) {
err = s->adder_ref + s->tag_ref - s->adder_out - s->tag_out;
#ifndef WITH_SEQUENCING
......@@ -167,17 +136,17 @@ int mpll_update(struct spll_main_state *s, int tag, int source)
#endif
y = pi_update((spll_pi_t *)&s->pi, err);
SPLL->DAC_MAIN = SPLL_DAC_MAIN_VALUE_W(y)
| SPLL_DAC_MAIN_DAC_SEL_W(s->dac_index);
y=0;
//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_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;
......@@ -198,6 +167,7 @@ int mpll_update(struct spll_main_state *s, int tag, int source)
s->adder_ref--;
}
}
if (ld_update((spll_lock_det_t *)&s->ld, err))
return SPLL_LOCKED;
......
......@@ -23,7 +23,7 @@ struct spll_main_state {
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;
......
......@@ -7,6 +7,7 @@
const char *build_revision;
const char *build_date;
static int calc_apr(int meas_min, int meas_max, int f_center )
{
// apr_min is in PPM
......@@ -56,7 +57,7 @@ int main(void)
uart_init_hw();
TRACE("WR Switch Real Time Subsystem (c) CERN 2011 - 2013\n");
TRACE("WR Switch Real Time Subsystem (c) CERN 2011 - 2014\n");
TRACE("Revision: %s, built %s.\n", build_revision, build_date);
TRACE("--");
......@@ -64,24 +65,17 @@ int main(void)
rts_init();
rtipc_init();
// spll_init(SPLL_MODE_DISABLED,0 ,0);
// check_vco_frequencies();
spll_init(SPLL_MODE_SLAVE,0 ,0);
for(;;)
{
uint32_t tics = timer_get_tics();
if(time_after(tics, start_tics + TICS_PER_SECOND/5))
{
// TRACE("tick!\n");
spll_show_stats();
start_tics = tics;
}
// rts_update();
// rtipc_action();
rts_update();
rtipc_action();
spll_update();
}
......
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