Commit 75b927a4 authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

moved from switch-sw: rewritten phase tracker stuff

Tom's fix for WR Switch makes ptracker much faster so that SPLL can handle all 18 ports.
parent 81f2dc66
......@@ -92,10 +92,10 @@ static inline void start_ptrackers(struct softpll_state *s)
static inline void update_ptrackers(struct softpll_state *s, int tag_value, int tag_source)
{
int i;
for (i = 0; i < spll_n_chan_ref; i++)
if (ptracker_mask & (1 << i))
ptracker_update(&s->ptrackers[i], tag_value, tag_source);
if(tag_source > spll_n_chan_ref)
return;
ptrackers_update(s->ptrackers, tag_value, tag_source);
}
static inline void sequencing_fsm(struct softpll_state *s, int tag_value, int tag_source)
......@@ -353,8 +353,7 @@ void spll_init(int mode, int slave_ref_channel, int align_pps)
PPSG->ESCR = PPSG_ESCR_PPS_VALID | PPSG_ESCR_TM_VALID;
for (i = 0; i < spll_n_chan_ref; i++)
ptracker_init(&s->ptrackers[i], spll_n_chan_ref, i,
PTRACKER_AVERAGE_SAMPLES);
ptracker_init(&s->ptrackers[i], i, PTRACKER_AVERAGE_SAMPLES);
TRACE_DEV
("softpll: mode %s, %d ref channels, %d out channels\n",
......@@ -489,7 +488,7 @@ int spll_read_ptracker(int channel, int32_t *phase_ps, int *enabled)
*phase_ps = to_picos(phase);
if (enabled)
*enabled = ptracker_mask & (1 << st->id_b) ? 1 : 0;
*enabled = ptracker_mask & (1 << st->id) ? 1 : 0;
return st->ready;
}
......@@ -513,7 +512,6 @@ void spll_show_stats()
softpll.ext.ld.locked, softpll.mpll.ld.locked,
softpll.helper.pi.y, softpll.mpll.pi.y, softpll.ext.pi.y,
softpll.delock_count, softpll.ext.sample_n);
}
int spll_shifter_busy(int channel)
......
......@@ -120,9 +120,5 @@ void spll_set_dac(int out_channel, int value);
/* Returns current DAC sample value for output (out_channel) */
int spll_get_dac(int out_channel);
/* For the shell command */
void spll_show_stats(void);
#endif // __SOFTPLL_NG_H
......@@ -11,85 +11,75 @@
#include "spll_ptracker.h"
void ptracker_init(struct spll_ptracker_state *s, int id_a,
int id_b, int num_avgs)
{
s->tag_a = s->tag_b = -1;
static int tag_ref = -1;
s->id_a = id_a;
s->id_b = id_b;
void ptracker_init(struct spll_ptracker_state *s, int id, int num_avgs)
{
s->id = id;
s->ready = 0;
s->n_avg = num_avgs;
s->acc = 0;
s->avg_count = 0;
s->sample_n = 0;
s->preserve_sign = 0;
s->enabled = 0;
}
void ptracker_start(struct spll_ptracker_state *s)
{
s->tag_a = s->tag_b = -1;
s->preserve_sign = 0;
s->enabled = 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);
spll_enable_tagger(s->id, 1);
spll_enable_tagger(spll_n_chan_ref, 1);
}
#define PTRACK_WRAP_LO (1<<(HPLL_N-2))
#define PTRACK_WRAP_HI (3*(1<<(HPLL_N-2)))
int ptracker_update(struct spll_ptracker_state *s, int tag,
int ptrackers_update(struct spll_ptracker_state *ptrackers, int tag,
int source)
{
const int adj_tab[16] = { /* psign */
/* 0 - 1/4 */ 0, 0, 0, -(1<<HPLL_N),
/* 1/4 - 1/2 */ 0, 0, 0, 0,
/* 1/2 - 3/4 */ 0, 0, 0, 0,
/* 3/4 - 1 */ (1<<HPLL_N), 0, 0, 0};
if(source == spll_n_chan_ref)
{
tag_ref = tag;
return 0;
}
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) {
register struct spll_ptracker_state *s = ptrackers + source;
if (delta <= PTRACK_WRAP_LO)
s->preserve_sign = -1;
else if (delta >= PTRACK_WRAP_HI)
s->preserve_sign = 1;
else
s->preserve_sign = 0;
if(!s->enabled)
return 0;
s->avg_count++;
s->acc = delta;
} else {
register int delta = (tag_ref - tag) & ((1 << HPLL_N) - 1);
register int index = delta >> (HPLL_N - 2);
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 == 0) {
/* hack: two since PTRACK_WRAP_LO/HI are in 1/4 and 3/4 of the scale,
we can use the two MSBs of delta and a trivial LUT instead, removing 2 branches */
s->preserve_sign = index << 2;
s->acc = delta;
s->avg_count ++;
} else {
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;
}
/* same hack again, using another lookup table to adjust for wraparound */
s->acc += delta + adj_tab[ index + s->preserve_sign ];
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;
return 0;
}
......@@ -15,20 +15,13 @@
#include "spll_common.h"
struct spll_ptracker_state {
int id_a, id_b;
int n_avg, acc, avg_count;
int enabled, id;
int n_avg, acc, avg_count, preserve_sign;
int phase_val, ready;
int tag_a, tag_b;
int sample_n;
int preserve_sign;
};
void ptracker_init(struct spll_ptracker_state *s, int id_a,
int id_b, int num_avgs);
void ptracker_init(struct spll_ptracker_state *s, int id, int num_avgs);
void ptracker_start(struct spll_ptracker_state *s);
int ptracker_update(struct spll_ptracker_state *s, int tag,
int source);
int ptrackers_update(struct spll_ptracker_state *ptrackers, int tag, int source);
#endif // __SPLL_PTRACKER_H
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