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) ...@@ -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) static inline void update_ptrackers(struct softpll_state *s, int tag_value, int tag_source)
{ {
int i; if(tag_source > spll_n_chan_ref)
for (i = 0; i < spll_n_chan_ref; i++) return;
if (ptracker_mask & (1 << i))
ptracker_update(&s->ptrackers[i], tag_value, tag_source); ptrackers_update(s->ptrackers, tag_value, tag_source);
} }
static inline void sequencing_fsm(struct softpll_state *s, int tag_value, int 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) ...@@ -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; PPSG->ESCR = PPSG_ESCR_PPS_VALID | PPSG_ESCR_TM_VALID;
for (i = 0; i < spll_n_chan_ref; i++) for (i = 0; i < spll_n_chan_ref; i++)
ptracker_init(&s->ptrackers[i], spll_n_chan_ref, i, ptracker_init(&s->ptrackers[i], i, PTRACKER_AVERAGE_SAMPLES);
PTRACKER_AVERAGE_SAMPLES);
TRACE_DEV TRACE_DEV
("softpll: mode %s, %d ref channels, %d out channels\n", ("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) ...@@ -489,7 +488,7 @@ int spll_read_ptracker(int channel, int32_t *phase_ps, int *enabled)
*phase_ps = to_picos(phase); *phase_ps = to_picos(phase);
if (enabled) if (enabled)
*enabled = ptracker_mask & (1 << st->id_b) ? 1 : 0; *enabled = ptracker_mask & (1 << st->id) ? 1 : 0;
return st->ready; return st->ready;
} }
...@@ -513,7 +512,6 @@ void spll_show_stats() ...@@ -513,7 +512,6 @@ void spll_show_stats()
softpll.ext.ld.locked, softpll.mpll.ld.locked, softpll.ext.ld.locked, softpll.mpll.ld.locked,
softpll.helper.pi.y, softpll.mpll.pi.y, softpll.ext.pi.y, softpll.helper.pi.y, softpll.mpll.pi.y, softpll.ext.pi.y,
softpll.delock_count, softpll.ext.sample_n); softpll.delock_count, softpll.ext.sample_n);
} }
int spll_shifter_busy(int channel) int spll_shifter_busy(int channel)
......
...@@ -120,9 +120,5 @@ void spll_set_dac(int out_channel, int value); ...@@ -120,9 +120,5 @@ void spll_set_dac(int out_channel, int value);
/* Returns current DAC sample value for output (out_channel) */ /* Returns current DAC sample value for output (out_channel) */
int spll_get_dac(int out_channel); int spll_get_dac(int out_channel);
/* For the shell command */
void spll_show_stats(void);
#endif // __SOFTPLL_NG_H #endif // __SOFTPLL_NG_H
...@@ -11,85 +11,75 @@ ...@@ -11,85 +11,75 @@
#include "spll_ptracker.h" #include "spll_ptracker.h"
void ptracker_init(struct spll_ptracker_state *s, int id_a, static int tag_ref = -1;
int id_b, int num_avgs)
{
s->tag_a = s->tag_b = -1;
s->id_a = id_a; void ptracker_init(struct spll_ptracker_state *s, int id, int num_avgs)
s->id_b = id_b; {
s->id = id;
s->ready = 0; s->ready = 0;
s->n_avg = num_avgs; s->n_avg = num_avgs;
s->acc = 0; s->acc = 0;
s->avg_count = 0; s->avg_count = 0;
s->sample_n = 0; s->enabled = 0;
s->preserve_sign = 0;
} }
void ptracker_start(struct spll_ptracker_state *s) 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->ready = 0;
s->acc = 0; s->acc = 0;
s->avg_count = 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, 1);
spll_enable_tagger(s->id_b, 1); spll_enable_tagger(spll_n_chan_ref, 1);
} }
#define PTRACK_WRAP_LO (1<<(HPLL_N-2)) int ptrackers_update(struct spll_ptracker_state *ptrackers, int tag,
#define PTRACK_WRAP_HI (3*(1<<(HPLL_N-2)))
int ptracker_update(struct spll_ptracker_state *s, int tag,
int source) 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) if(!s->enabled)
s->preserve_sign = -1; return 0;
else if (delta >= PTRACK_WRAP_HI)
s->preserve_sign = 1;
else
s->preserve_sign = 0;
s->avg_count++; register int delta = (tag_ref - tag) & ((1 << HPLL_N) - 1);
s->acc = delta; register int index = delta >> (HPLL_N - 2);
} else {
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) { /* same hack again, using another lookup table to adjust for wraparound */
s->phase_val = s->acc / s->n_avg; s->acc += delta + adj_tab[ index + s->preserve_sign ];
s->ready = 1; s->avg_count ++;
s->acc = 0;
s->avg_count = 0;
}
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 @@ ...@@ -15,20 +15,13 @@
#include "spll_common.h" #include "spll_common.h"
struct spll_ptracker_state { struct spll_ptracker_state {
int id_a, id_b; int enabled, id;
int n_avg, acc, avg_count; int n_avg, acc, avg_count, preserve_sign;
int phase_val, ready; 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, void ptracker_init(struct spll_ptracker_state *s, int id, int num_avgs);
int id_b, int num_avgs);
void ptracker_start(struct spll_ptracker_state *s); void ptracker_start(struct spll_ptracker_state *s);
int ptrackers_update(struct spll_ptracker_state *ptrackers, int tag, int source);
int ptracker_update(struct spll_ptracker_state *s, int tag,
int source);
#endif // __SPLL_PTRACKER_H #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