-added sync/adjust callback for freq trimming
-fixed burst function with no outputs -cleanup some old float testing code
This commit is contained in:
parent
f1000547ab
commit
8b86cd6d33
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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()
|
||||
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)
|
||||
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()
|
||||
#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
|
||||
|
|
Loading…
Reference in New Issue