diff options
author | trondeau | 2008-02-06 15:54:54 +0000 |
---|---|---|
committer | trondeau | 2008-02-06 15:54:54 +0000 |
commit | 42ad2adb86981f4488edbe33169683f787b807c3 (patch) | |
tree | 94c24204ceecc1d3994e096422f67dd44fbaefac /gnuradio-core/src | |
parent | 00e5a82e769411988244fe6e3eb3fdbb30562169 (diff) | |
download | gnuradio-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
Diffstat (limited to 'gnuradio-core/src')
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")) |