From 8b86cd6d331e370e0c4a2e01510af38a3957694c Mon Sep 17 00:00:00 2001 From: tvoid Date: Tue, 8 Apr 2008 14:44:00 -0600 Subject: -added sync/adjust callback for freq trimming -fixed burst function with no outputs -cleanup some old float testing code --- gsm-tvoid/src/lib/gsm.i | 5 +- gsm-tvoid/src/lib/gsm_burst.cc | 8 +++- gsm-tvoid/src/lib/gsm_burst.h | 7 +-- gsm-tvoid/src/lib/gsm_burst_cf.cc | 5 +- gsm-tvoid/src/lib/gsm_burst_ff.cc | 11 +++-- gsm-tvoid/src/python/gsm_scan.py | 99 ++++++++++++++++++--------------------- 6 files changed, 68 insertions(+), 67 deletions(-) diff --git a/gsm-tvoid/src/lib/gsm.i b/gsm-tvoid/src/lib/gsm.i index 9d653ac..81e9062 100755 --- a/gsm-tvoid/src/lib/gsm.i +++ b/gsm-tvoid/src/lib/gsm.i @@ -43,8 +43,9 @@ #define CLK_CORR_TRACK 0x00000010 //adjust timing based on correlation offsets -#define BURST_CB_ADJ_OFFSET 1 -#define BURST_CB_TUNE 2 +#define BURST_CB_SYNC_OFFSET 1 +#define BURST_CB_ADJ_OFFSET 2 +#define BURST_CB_TUNE 3 //EQ options enum EQ_TYPE { diff --git a/gsm-tvoid/src/lib/gsm_burst.cc b/gsm-tvoid/src/lib/gsm_burst.cc index 97e8682..f18dcae 100755 --- a/gsm-tvoid/src/lib/gsm_burst.cc +++ b/gsm-tvoid/src/lib/gsm_burst.cc @@ -366,7 +366,7 @@ void gsm_burst::calc_freq_offset(void) for (int j = start; j <= end; j++) { sum += d_burst_buffer[j]; } - float mean = sum / ((float)USEFUL_BITS - 2.0 * (float)padding); + float mean = sum / ((float)USEFUL_BITS - (2.0 * (float)padding) ); float p_off = mean - (M_PI / 2); d_freq_offset = p_off * 1625000.0 / (12.0 * M_PI); @@ -651,7 +651,11 @@ int gsm_burst::get_burst(void) #ifndef TEST_TUNE_TIMING if (p_tuner) { - p_tuner->calleval(BURST_CB_ADJ_OFFSET); + if (SYNCHRONIZED == d_sync_state) + p_tuner->calleval(BURST_CB_ADJ_OFFSET); + else + p_tuner->calleval(BURST_CB_SYNC_OFFSET); + } #endif diff --git a/gsm-tvoid/src/lib/gsm_burst.h b/gsm-tvoid/src/lib/gsm_burst.h index 79d72d6..d6ab381 100755 --- a/gsm-tvoid/src/lib/gsm_burst.h +++ b/gsm-tvoid/src/lib/gsm_burst.h @@ -13,7 +13,7 @@ //Testing Modes //Tune test measures hopping latency by hopping between good and empty ARFCNs -#define TEST_TUNE_TIMING +#undef TEST_TUNE_TIMING #define TEST_TUNE_GOOD_ARFCN 658 #define TEST_TUNE_EMPTY_ARFCN 655 @@ -78,8 +78,9 @@ enum EQ_TYPE { EQ_VITERBI }; -#define BURST_CB_ADJ_OFFSET 1 -#define BURST_CB_TUNE 2 +#define BURST_CB_SYNC_OFFSET 1 +#define BURST_CB_ADJ_OFFSET 2 +#define BURST_CB_TUNE 3 class gsm_burst; diff --git a/gsm-tvoid/src/lib/gsm_burst_cf.cc b/gsm-tvoid/src/lib/gsm_burst_cf.cc index e9fe0fc..a584cd6 100755 --- a/gsm-tvoid/src/lib/gsm_burst_cf.cc +++ b/gsm-tvoid/src/lib/gsm_burst_cf.cc @@ -65,6 +65,7 @@ int gsm_burst_cf::general_work (int noutput_items, int ii=0; int rval = 0; //default to no output + int do_output = output_items.size() > 0 ? 1 : 0; int ninput = ninput_items[0]; //fprintf(stderr,"#i=%d/#o=%d",n_input,noutput_items); @@ -96,7 +97,7 @@ int gsm_burst_cf::general_work (int noutput_items, if (get_burst()) { //found a burst, send to output - if (out) { + if (do_output) { //ensure that output data is in range int b = d_burst_start; if (b < 0) @@ -105,8 +106,8 @@ int gsm_burst_cf::general_work (int noutput_items, b = 2 * MAX_CORR_DIST - 1; memcpy(out+rval*USEFUL_BITS, d_burst_buffer + b, USEFUL_BITS*sizeof(float)); - rval++; } + rval++; switch ( d_clock_options & QB_MASK ) { case QB_QUARTER: //extra 1/4 bit each burst diff --git a/gsm-tvoid/src/lib/gsm_burst_ff.cc b/gsm-tvoid/src/lib/gsm_burst_ff.cc index f4aec06..89b513f 100755 --- a/gsm-tvoid/src/lib/gsm_burst_ff.cc +++ b/gsm-tvoid/src/lib/gsm_burst_ff.cc @@ -52,9 +52,10 @@ int gsm_burst_ff::general_work (int noutput_items, int ii=0; int rval = 0; //default to no output - + int do_output = output_items.size() > 0 ? 1 : 0; + int n_input = ninput_items[0]; - //fprintf(stderr,"#i=%d/#o=%d",n_input,noutput_items); +// fprintf(stderr,"out=%8.8x/#i=%d/#o=%d",(unsigned)out,n_input,noutput_items); while (( rval < noutput_items) && ( ii < n_input ) ) { @@ -69,7 +70,7 @@ int gsm_burst_ff::general_work (int noutput_items, if (get_burst()) { //found a burst, send to output - if (out) { + if (do_output) { //ensure that output data is in range int b = d_burst_start; if (b < 0) @@ -78,8 +79,8 @@ int gsm_burst_ff::general_work (int noutput_items, b = 2 * MAX_CORR_DIST - 1; memcpy(out+rval*USEFUL_BITS, d_burst_buffer + b, USEFUL_BITS*sizeof(float)); - rval++; } + rval++; switch ( d_clock_options & QB_MASK ) { case QB_QUARTER: //Can't do this in the FF version @@ -100,7 +101,7 @@ int gsm_burst_ff::general_work (int noutput_items, ii++; } - //fprintf(stderr,"/ii=%d/rval=%d\n",ii,rval); +// fprintf(stderr,"/ii=%d/rval=%d\n",ii,rval); consume_each (ii); diff --git a/gsm-tvoid/src/python/gsm_scan.py b/gsm-tvoid/src/python/gsm_scan.py index 9d5cbcf..6e09f7f 100755 --- a/gsm-tvoid/src/python/gsm_scan.py +++ b/gsm-tvoid/src/python/gsm_scan.py @@ -31,19 +31,37 @@ class burst_callback(gr.feval_ll): def __init__(self, fg): gr.feval_ll.__init__(self) self.fg = fg - + self.offset_mean_num = 30 #number of FCCH offsets to average + self.offset_vals = [] + def eval(self, x): try: - #print "burst_callback: ", x, "\n"; - if gsm.BURST_CB_ADJ_OFFSET == x: - #return 0 - #TODO: rework so this will work on file input + #TODO: rework so this will work on file input + if gsm.BURST_CB_SYNC_OFFSET == x: + last_offset = self.fg.burst.last_freq_offset() + self.fg.offset -= last_offset + print "burst_callback: SYNC_OFFSET:", last_offset, " ARFCN: ", self.fg.arfcn, "\n"; + self.fg.set_channel(self.fg.arfcn) + + elif gsm.BURST_CB_ADJ_OFFSET == x: last_offset = self.fg.burst.last_freq_offset() - if 20000.0 > abs(last_offset) > 500.0: - self.fg.offset -= last_offset - print "burst_callback: ADJ_OFFSET:", last_offset, " ARFCN: ", self.fg.arfcn, "\n"; - self.fg.set_channel(self.fg.arfcn) + #print "burst_callback: ADJ_OFFSET:", last_offset, " ARFCN: ", self.fg.arfcn, "\n"; + self.offset_vals.append(last_offset) + + if len(self.offset_vals) >= self.offset_mean_num: + sum = 0.0 + while len(self.offset_vals): + sum += self.offset_vals.pop(0) + + mean_offset = sum / self.offset_mean_num + self.fg.offset -= mean_offset + + #retune if greater than 100 Hz + if mean_offset > 100.0: + print "burst_callback: mean offset:", mean_offset, "\n"; + self.fg.set_channel(self.fg.arfcn) + elif gsm.BURST_CB_TUNE == x: print "burst_callback: BURST_CB_TUNE: ARFCN: ", self.fg.burst.next_arfcn, "\n"; self.fg.set_channel(self.fg.burst.next_arfcn) @@ -196,25 +214,25 @@ class app_flow_graph(stdgui.gui_flow_graph): sps = input_rate/gsm_symb_rate - # Attempt to enable realtime scheduling - r = gr.enable_realtime_scheduling() - if r == gr.RT_OK: - realtime = True - print "Realtime scheduling ENABLED" - else: - realtime = False - print "Realtime scheduling FAILED" - -# if options.fusb_block_size == 0 and options.fusb_nblocks == 0: - if realtime: # be more aggressive - options.fusb_block_size = gr.prefs().get_long('fusb', 'rt_block_size', 1024) - options.fusb_nblocks = gr.prefs().get_long('fusb', 'rt_nblocks', 16) - else: - options.fusb_block_size = gr.prefs().get_long('fusb', 'block_size', 4096) - options.fusb_nblocks = gr.prefs().get_long('fusb', 'nblocks', 16) - - print "fusb_block_size =", options.fusb_block_size - print "fusb_nblocks =", options.fusb_nblocks +# # Attempt to enable realtime scheduling +# r = gr.enable_realtime_scheduling() +# if r == gr.RT_OK: +# realtime = True +# print "Realtime scheduling ENABLED" +# else: +# realtime = False +# print "Realtime scheduling FAILED" +# +# # if options.fusb_block_size == 0 and options.fusb_nblocks == 0: +# if realtime: # be more aggressive +# options.fusb_block_size = gr.prefs().get_long('fusb', 'rt_block_size', 1024) +# options.fusb_nblocks = gr.prefs().get_long('fusb', 'rt_nblocks', 16) +# else: +# options.fusb_block_size = gr.prefs().get_long('fusb', 'block_size', 4096) +# options.fusb_nblocks = gr.prefs().get_long('fusb', 'nblocks', 16) +# +# print "fusb_block_size =", options.fusb_block_size +# print "fusb_nblocks =", options.fusb_nblocks # Build the flowgraph # Setup our input source @@ -302,31 +320,6 @@ class app_flow_graph(stdgui.gui_flow_graph): self.clocked_scope = scopesink.scope_sink_f(self, panel, sample_rate=gsm_symb_rate,v_scale=1) self.connect(self.clocker, self.clocked_scope) - elif options.decoder.count("F"): - #configure clock recovery - gain_mu = 0.01 - gain_omega = .25 * gain_mu * gain_mu # critically damped - self.clocker = gr.clock_recovery_mm_cc( sps, - gain_omega, - 0.5, #mu - gain_mu, - 0.3) #omega_relative_limit, - - - # configure demodulator - self.demod = gr.quadrature_demod_cf(1); - - self.burst = gsm.burst_ff() - self.connect(self.filter, self.clocker, self.demod, self.burst) - - if self.scopes.count("d"): - self.demod_scope = scopesink.scope_sink_f(self, panel, sample_rate=input_rate) - self.connect(self.demod, self.demod_scope) - - if self.scopes.count("c"): - self.clocked_scope = scopesink.scope_sink_f(self, panel, sample_rate=gsm_symb_rate,v_scale=1) - self.connect(self.clocker, self.clocked_scope) - # setup decoder parameters # equalizer -- cgit v1.2.3