diff --git a/examples/packet_phy_tx.grc b/examples/packet_phy_tx.grc index 7d6128ccbb351093c0398bc2f85f9863e2c3870b..e91a6427df0ac49e1ce254b22ac48e84a3500bd0 100644 --- a/examples/packet_phy_tx.grc +++ b/examples/packet_phy_tx.grc @@ -108,7 +108,7 @@ blocks: parameters: alpha: excess_bw comment: '' - gain: nfilts/2 + gain: nfilts ntaps: 5*sps*nfilts samp_rate: nfilts sym_rate: '1.0' diff --git a/grc/elen90089_corr_est_cc.block.yml b/grc/elen90089_corr_est_cc.block.yml index fa8de8cae93f145d501df25024527a491300fe1d..4db7551c6370f735e316c251db60cfc6167ab274 100644 --- a/grc/elen90089_corr_est_cc.block.yml +++ b/grc/elen90089_corr_est_cc.block.yml @@ -19,11 +19,15 @@ inputs: - label: in domain: stream dtype: complex + outputs: - label: out domain: stream dtype: complex -- label: out +- label: cfo + domain: message + optional: True +- label: corr domain: stream dtype: float optional: True diff --git a/lib/corr_est_cc_impl.cc b/lib/corr_est_cc_impl.cc index 5cb25a7e5b63ecd591b01eedf81bc1d79e623a03..cd9e757d3c1bcd4a6cddb2c6c180e11d335d9bb2 100644 --- a/lib/corr_est_cc_impl.cc +++ b/lib/corr_est_cc_impl.cc @@ -36,6 +36,8 @@ corr_est_cc_impl::corr_est_cc_impl(const std::vector<gr_complex>& sequence, { set_max_noutput_items(s_nitems); set_sequence(sequence); + + message_port_register_out(pmt::mp("cfo")); } corr_est_cc_impl::~corr_est_cc_impl() {} @@ -54,14 +56,14 @@ void corr_est_cc_impl::set_sequence(const std::vector<gr_complex>& sequence) // create time-reversed conjugate of training sequence for filtering std::vector<gr_complex> taps(sequence.size()); std::reverse_copy(sequence.begin(), sequence.end(), taps.begin()); - float scale = 0.0; + d_scale = 0.0; for (size_t i = 0; i < taps.size(); i++) { taps[i] = std::conj(taps[i]); - scale += std::norm(taps[i]); + d_scale += std::norm(taps[i]); } - scale = 1.0 / sqrt(scale); + d_scale = 1.0 / sqrt(d_scale); for (size_t i = 0; i < taps.size(); i++) { - taps[i] *= scale; + taps[i] *= d_scale; } // set taps and block output multiple to FFT kernel's internal nsamples @@ -150,25 +152,45 @@ int corr_est_cc_impl::work(int noutput_items, if (corr_mag[i] > d_threshold) { // coarse frequency estimate double freq_est = estimate_freq_offset(&in[i]); + + // single-tap (inverse) channel estimate + gr_complex chan_est = d_corr[i] * d_scale; + chan_est = conj(chan_est) / (chan_est*conj(chan_est)); + + // time phase estimate - center-of-mass (3 samples) + double nom = corr_mag[i-1] + 2*corr_mag[i] + 3*corr_mag[i+1]; + double den = corr_mag[i-1] + corr_mag[i] + corr_mag[i+1]; + double time_est = (nom/den) - 2.0; + + // send frequency correction message + int offset = nitems_written(0) + i; + pmt::pmt_t cmd = pmt::make_dict(); + cmd = pmt::dict_add(cmd, + pmt::mp("offset"), + pmt::from_long(offset)); + cmd = pmt::dict_add(cmd, + pmt::mp("inc"), + pmt::from_double(-freq_est)); + message_port_pub(pmt::mp("cfo"), cmd); // tag output - add_item_tag(0, nitems_written(0) + i, - pmt::intern("corr_start"), - pmt::from_double(corr_mag[i]), - d_src_id); - add_item_tag(0, nitems_written(0) + i, - pmt::intern("freq_est"), - pmt::from_double(freq_est), - d_src_id); - if (output_items.size() > 1) { - add_item_tag(1, nitems_written(0) + i, + for(int ch = 0; ch < output_items.size(); ch++) { + add_item_tag(ch, offset, pmt::intern("corr_start"), pmt::from_double(corr_mag[i]), d_src_id); - add_item_tag(1, nitems_written(0) + i, + add_item_tag(ch, offset, pmt::intern("freq_est"), pmt::from_double(freq_est), d_src_id); + add_item_tag(ch, offset, + pmt::intern("chan_est"), + pmt::from_complex(chan_est), + d_src_id); + add_item_tag(ch, offset, + pmt::intern("time_est"), + pmt::from_double(time_est), + d_src_id); } // skip remaining symbols in sequence diff --git a/lib/corr_est_cc_impl.h b/lib/corr_est_cc_impl.h index 9fc44e640ea25a0f498340ced0f26d79080c3a2b..479dac5282ac6f1f45d1085acfed1690209c5031 100644 --- a/lib/corr_est_cc_impl.h +++ b/lib/corr_est_cc_impl.h @@ -28,6 +28,7 @@ private: volk::vector<gr_complex> d_corr; volk::vector<float> d_corr_mag; volk::vector<float> d_y_mag; + float d_scale; float d_y_accum; int d_skip; diff --git a/python/packet_phy_tx.py b/python/packet_phy_tx.py index ce7df6e730826b0eb1abdd6cc085aecd68ff1582..831abba6f9a4b73223f3b135d21e33a1ddf6db65 100644 --- a/python/packet_phy_tx.py +++ b/python/packet_phy_tx.py @@ -43,7 +43,7 @@ class packet_phy_tx(gr.hier_block2): # Variables ################################################## self.nfilts = nfilts = 32 - self.rrc_taps = rrc_taps = firdes.root_raised_cosine(nfilts/2, nfilts,1.0, excess_bw, 5*sps*nfilts) + self.rrc_taps = rrc_taps = firdes.root_raised_cosine(nfilts, nfilts,1.0, excess_bw, 5*sps*nfilts) self.taps_per_filt = taps_per_filt = len(rrc_taps)/nfilts self.header_format_cdc_0 = header_format_cdc_0 = elen90089.header_format_cdc(digital.packet_utils.default_access_code, 3, 1) self.hdr_encoder = hdr_encoder = fec.dummy_encoder_make(1500)