summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrondeau2008-02-06 15:54:54 +0000
committertrondeau2008-02-06 15:54:54 +0000
commit42ad2adb86981f4488edbe33169683f787b807c3 (patch)
tree94c24204ceecc1d3994e096422f67dd44fbaefac
parent00e5a82e769411988244fe6e3eb3fdbb30562169 (diff)
downloadgnuradio-42ad2adb86981f4488edbe33169683f787b807c3.tar.gz
gnuradio-42ad2adb86981f4488edbe33169683f787b807c3.tar.bz2
gnuradio-42ad2adb86981f4488edbe33169683f787b807c3.zip
Merging trondeau/ofdmfix into branch at -r7582:7586. This allows for over-the-air OFDM. Works with all modulations and tested both send and receive on different computers/USRPs. Misses a few packets, so it's not perfect.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@7587 221aa14e-8319-0410-a670-987f0aec2ac5
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.cc78
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_sampler.cc3
-rw-r--r--gnuradio-core/src/lib/gengen/gr_peak_detector_XX.cc.t2
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/ofdm_receiver.py1
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pn.py13
5 files changed, 54 insertions, 43 deletions
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.cc b/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.cc
index 0fa6a3d3e..40a0ed852 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.cc
@@ -48,7 +48,7 @@ gr_ofdm_frame_acquisition::gr_ofdm_frame_acquisition (unsigned occupied_carriers
const std::vector<gr_complex> &known_symbol,
unsigned int max_fft_shift_len)
: gr_block ("ofdm_frame_acquisition",
- gr_make_io_signature2 (2, 2, sizeof(gr_complex)*fft_length, sizeof(char)),
+ gr_make_io_signature (1, 1, sizeof(gr_complex)*fft_length),
gr_make_io_signature2 (2, 2, sizeof(gr_complex)*occupied_carriers, sizeof(char))),
d_occupied_carriers(occupied_carriers),
d_fft_length(fft_length),
@@ -101,44 +101,64 @@ gr_ofdm_frame_acquisition::coarse_freq_comp(int freq_delta, int symbol_count)
//return d_phase_lut[MAX_NUM_SYMBOLS * (d_freq_shift_len + freq_delta) + symbol_count];
}
-
-
bool
gr_ofdm_frame_acquisition::correlate(const gr_complex *symbol, int zeros_on_left)
{
- unsigned int i = 0, j = 0;
+ unsigned int i = 0;
+ int search_delta = 0;
+ bool found = false;
+
+ gr_complex h_sqrd = gr_complex(0.0,0.0);
+ float power = 0.0F;
std::fill(d_symbol_phase_diff.begin(), d_symbol_phase_diff.end(), 0);
for(i = 0; i < d_fft_length-2; i++) {
d_symbol_phase_diff[i] = fabs(gr_fast_atan2f(symbol[i]) - gr_fast_atan2f(symbol[i+2]));
}
- int index = 0;
- float max = 0, sum=0;
- for(i = zeros_on_left - d_freq_shift_len; i < zeros_on_left + d_freq_shift_len; i+=2) {
- sum = 0;
- for(j = 0; j < d_occupied_carriers; j++) {
- sum += (d_known_phase_diff[j] * d_symbol_phase_diff[i+j]);
+
+ while(!found && ((unsigned)abs(search_delta) <= d_freq_shift_len)) {
+ h_sqrd = gr_complex(0.0,0.0);
+ power = 0.0F;
+
+ //FIXME: power calculation doesn't really make sense
+ for(i = 0; i < d_occupied_carriers; i++) {
+ h_sqrd += (d_known_phase_diff[i] * d_symbol_phase_diff[i+zeros_on_left+search_delta]);
+ power += d_known_phase_diff[i]*d_known_phase_diff[i];
}
- if(fabs(sum) > max) {
- max = sum;
- index = i;
+
+ if(VERBOSE) {
+ printf("bin %d\th_sqrd = ( %f, %f )\t power = %f\t real(h)/p = %f\t angle = %f\n",
+ search_delta, h_sqrd.real(), h_sqrd.imag(), power, h_sqrd.real()/power, arg(h_sqrd));
}
- }
-
- d_coarse_freq = index - zeros_on_left;
- if(VERBOSE) {
- fprintf(stderr, "Coarse Freq Offset: %d\n", d_coarse_freq);
- for(i = 0; i < 40; i++) {
- fprintf(stderr, "%+.4f %+.4f\n", d_known_phase_diff[i],
- d_symbol_phase_diff[zeros_on_left+d_coarse_freq+i]);
+ //FIXME: these threshold values are arbitrary, although the decision metric is very good
+ // even at very low SNR
+ if((h_sqrd.real() > 0.95*power) && (h_sqrd.real() < 1.1*power)) {
+ found = true;
+ d_coarse_freq = search_delta;
+ d_phase_count = 1;
+
+ //printf("bin %d\th_sqrd = ( %f, %f )\t power = %f\t real(h)/p = %f\t angle = %f\n",
+ // search_delta, h_sqrd.real(), h_sqrd.imag(), power, h_sqrd.real()/power, arg(h_sqrd));
+
+ if(VERBOSE) {
+ printf("CORR: Found, bin %d\tdB\tcorr power fraction %f\n",
+ search_delta, h_sqrd.real()/power);
+ }
+ break;
+ }
+ else {
+ if(search_delta <= 0)
+ search_delta = (-search_delta) + 2;
+ else
+ search_delta = -search_delta;
}
}
-
- return true; //FIXME: don't need ot return anything now
+ return found;
}
+
void
gr_ofdm_frame_acquisition::calculate_equalizer(const gr_complex *symbol, int zeros_on_left)
{
@@ -184,7 +204,6 @@ gr_ofdm_frame_acquisition::general_work(int noutput_items,
gr_vector_void_star &output_items)
{
const gr_complex *symbol = (const gr_complex *)input_items[0];
- const char *trigger = (const char *)input_items[1];
gr_complex *out = (gr_complex *) output_items[0];
char *sig = (char *) output_items[1];
@@ -193,19 +212,15 @@ gr_ofdm_frame_acquisition::general_work(int noutput_items,
int zeros_on_left = (int)ceil(unoccupied_carriers/2.0);
int found = 0;
- for(int i = 0; i < ninput_items[1]; i++) {
- found += trigger[i];
- }
-
+ found = correlate(symbol, zeros_on_left);
if(found) {
d_phase_count = 1;
- correlate(symbol, zeros_on_left);
calculate_equalizer(symbol, zeros_on_left);
sig[0] = 1;
}
else {
sig[0] = 0;
- }
+ }
for(unsigned int i = 0; i < d_occupied_carriers; i++) {
out[i] = d_hestimate[i]*coarse_freq_comp(d_coarse_freq,d_phase_count)
@@ -217,7 +232,6 @@ gr_ofdm_frame_acquisition::general_work(int noutput_items,
d_phase_count = 1;
}
- consume(0,1);
- consume(1,ninput_items[1]);
+ consume_each(1);
return 1;
}
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc b/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
index 6216df791..c52945656 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
@@ -70,8 +70,7 @@ gr_ofdm_sampler::general_work (int noutput_items,
int i=d_fft_length-1;
// FIXME: This is where we miss if the regeneration happens too soon.
- //while(!found && i<std::min(ninput_items[0],ninput_items[1]) ) {
- while(i<std::min(ninput_items[0],ninput_items[1]) ) {
+ while(!found && i<std::min(ninput_items[0],ninput_items[1]) ) {
if(trigger[i]) {
found = 1;
index = i++;
diff --git a/gnuradio-core/src/lib/gengen/gr_peak_detector_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_peak_detector_XX.cc.t
index 6808deae2..e2f6b5026 100644
--- a/gnuradio-core/src/lib/gengen/gr_peak_detector_XX.cc.t
+++ b/gnuradio-core/src/lib/gengen/gr_peak_detector_XX.cc.t
@@ -105,6 +105,6 @@ int
}
else { // only return up to passing the threshold
//printf("Leave in State 1, only produced %d of %d\n",peak_ind,noutput_items);
- return peak_ind;
+ return peak_ind+1;
}
}
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_receiver.py b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_receiver.py
index 9592755b1..c5cb4df5c 100644
--- a/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_receiver.py
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_receiver.py
@@ -100,7 +100,6 @@ class ofdm_receiver(gr.hier_block2):
self.connect(self, self.chan_filt)
self.connect(self.chan_filt, self.ofdm_sync, self.fft_demod, (self.ofdm_frame_acq,0))
- self.connect((self.ofdm_sync,1), (self.ofdm_frame_acq,1))
self.connect((self.ofdm_frame_acq,0), (self,0))
self.connect((self.ofdm_frame_acq,1), (self,1))
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pn.py b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pn.py
index 0ec22cced..71140bca5 100644
--- a/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pn.py
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pn.py
@@ -35,7 +35,7 @@ class ofdm_sync_pn(gr.hier_block2):
gr.hier_block2.__init__(self, "ofdm_sync_pn",
gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
- gr.io_signature2(2, 2, gr.sizeof_gr_complex*fft_length, gr.sizeof_char)) # Output signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex*fft_length)) # Output signature
# FIXME: when converting to hier_block2's, the output signature
# should be the output of the divider (the normalized peaks) and
@@ -86,9 +86,9 @@ class ofdm_sync_pn(gr.hier_block2):
self.sigmix = gr.multiply_cc()
#ML measurements input to sampler block and detect
- #self.sub1 = gr.add_const_ff(-1)
- #self.pk_detect = gr.peak_detector_fb(0.20, 0.20, 30, 0.001)
- self.pk_detect = gr.peak_detector2_fb(9)
+ self.sub1 = gr.add_const_ff(-1)
+ self.pk_detect = gr.peak_detector_fb(0.20, 0.20, 30, 0.001)
+ #self.pk_detect = gr.peak_detector2_fb(9)
#self.pk_detect = gr.threshold_detector_fb(0.5)
self.regen = gr.regenerate_bb(symbol_length)
@@ -123,15 +123,14 @@ class ofdm_sync_pn(gr.hier_block2):
self.matched_filter = gr.fir_filter_fff(1,matched_filter_taps)
self.connect(self.normalize, self.matched_filter)
- #self.connect(self.matched_filter, self.sub1, self.pk_detect)
- self.connect(self.matched_filter, self.pk_detect)
+ self.connect(self.matched_filter, self.sub1, self.pk_detect)
+ #self.connect(self.matched_filter, self.pk_detect)
self.connect(self.pk_detect, self.regen)
self.connect(self.regen, (self.sampler,1))
self.connect(self.pk_detect, (self.sample_and_hold,1))
# Set output from sampler
self.connect(self.sampler, (self,0))
- self.connect(self.pk_detect, (self,1))
if logging:
self.connect(self.matched_filter, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-mf_f.dat"))