diff --git a/grc/satnogs_upsat_fsk_frame_encoder.xml b/grc/satnogs_upsat_fsk_frame_encoder.xml index 48efc6c..95bef59 100644 --- a/grc/satnogs_upsat_fsk_frame_encoder.xml +++ b/grc/satnogs_upsat_fsk_frame_encoder.xml @@ -4,7 +4,7 @@ satnogs_upsat_fsk_frame_encoder satnogs import satnogs - satnogs.upsat_fsk_frame_encoder($preamble, $sync_word, $append_crc, $whitening, $manchester, $msb_first) + satnogs.upsat_fsk_frame_encoder($preamble, $sync_word, $append_crc, $whitening, $manchester, $msb_first, $settling_samples) Frame Preamble @@ -73,6 +73,13 @@ False + + + Number of zero settling samples + settling_samples + 64 + int + pdu diff --git a/include/satnogs/upsat_fsk_frame_encoder.h b/include/satnogs/upsat_fsk_frame_encoder.h index 23a7902..ca8bfc5 100644 --- a/include/satnogs/upsat_fsk_frame_encoder.h +++ b/include/satnogs/upsat_fsk_frame_encoder.h @@ -64,12 +64,21 @@ namespace gr * * @param msb_first if set to true, the the treansmission starts from the * MSB of each byte. + * + * @param settling_samples the number of zero samples that the encoder + * should append after the end of the FSK frame. This is especially + * important when an arbitrary in-out ratio resampler is used. The + * arbitrary in-out ratio of samples will cause the stream tags to be + * delivered at the sink block out-of-sync causing the frame transmission + * to terminate sooner. */ static sptr make (const std::vector& preamble, - const std::vector& sync_word, bool append_crc = true, + const std::vector& sync_word, + bool append_crc = true, bool whitening = false, bool manchester = false, - bool msb_first = true); + bool msb_first = true, + size_t settling_samples = 64); }; } // namespace satnogs diff --git a/lib/upsat_fsk_frame_encoder_impl.cc b/lib/upsat_fsk_frame_encoder_impl.cc index 7b2e0f6..970d9c8 100644 --- a/lib/upsat_fsk_frame_encoder_impl.cc +++ b/lib/upsat_fsk_frame_encoder_impl.cc @@ -38,11 +38,14 @@ namespace gr const std::vector& sync_word, bool append_crc, bool whitening, bool manchester, - bool msb_first) + bool msb_first, + size_t settling_samples) { return gnuradio::get_initial_sptr ( - new upsat_fsk_frame_encoder_impl (preamble, sync_word, append_crc, - whitening, manchester, msb_first)); + new upsat_fsk_frame_encoder_impl (preamble, sync_word, + append_crc, + whitening, manchester, msb_first, + settling_samples)); } /* @@ -50,8 +53,10 @@ namespace gr */ upsat_fsk_frame_encoder_impl::upsat_fsk_frame_encoder_impl ( const std::vector& preamble, - const std::vector& sync_word, bool append_crc, bool whitening, - bool manchester, bool msb_first) : + const std::vector& sync_word, + bool append_crc, bool whitening, + bool manchester, bool msb_first, + size_t settling_samples) : gr::sync_block ("upsat_fsk_frame_encoder", gr::io_signature::make (0, 0, 0), gr::io_signature::make (1, 1, sizeof(float))), @@ -65,6 +70,7 @@ namespace gr d_msb_first(msb_first), d_max_pdu_len(d_preamble_len + d_sync_word_len + sizeof(uint8_t) + UPSAT_MAX_FRAME_LEN + sizeof(uint16_t)), + d_settling_samples(settling_samples), d_encoded(0), d_pdu_len(0), d_scrambler(0x21, 0x1FF, 9) @@ -81,10 +87,7 @@ namespace gr * User def. User def. 1B 1-255 B 2 B */ d_pdu = new uint8_t[d_max_pdu_len]; - - if(!d_pdu) { - throw std::runtime_error("Could not allocate memory"); - } + d_pdu_encoded = new float[d_max_pdu_len*8 + d_settling_samples]; /* Copy the preamble at the start of the pdu */ memcpy(d_pdu, d_preamble.data(), d_preamble_len); @@ -97,6 +100,7 @@ namespace gr upsat_fsk_frame_encoder_impl::~upsat_fsk_frame_encoder_impl () { delete [] d_pdu; + delete [] d_pdu_encoded; } inline void @@ -137,6 +141,24 @@ namespace gr } } + inline void + upsat_fsk_frame_encoder_impl::add_sob (uint64_t item) + { + static const pmt::pmt_t sob_key = pmt::string_to_symbol ("tx_sob"); + static const pmt::pmt_t value = pmt::PMT_T; + static const pmt::pmt_t srcid = pmt::string_to_symbol (alias ()); + add_item_tag (0, item, sob_key, value, srcid); + } + + inline void + upsat_fsk_frame_encoder_impl::add_eob (uint64_t item) + { + static const pmt::pmt_t eob_key = pmt::string_to_symbol ("tx_eob"); + static const pmt::pmt_t value = pmt::PMT_T; + static const pmt::pmt_t srcid = pmt::string_to_symbol (alias ()); + add_item_tag (0, item, eob_key, value, srcid); + } + int upsat_fsk_frame_encoder_impl::work (int noutput_items, gr_vector_const_void_star &input_items, @@ -183,7 +205,7 @@ namespace gr } /* - * Whitening is performed on all byes except preamble and SYNC fields + * Whitening is performed on all bytes except preamble and SYNC fields */ if(d_whitening){ d_scrambler.reset(); @@ -193,22 +215,38 @@ namespace gr } d_pdu_len += d_preamble_len + d_sync_word_len + 1; + + /* + * NRZ Encode the whole frame + */ + if (d_msb_first) { + map_msb_first (d_pdu_encoded, d_pdu_len * 8); + } + else { + map_lsb_first (d_pdu_encoded, d_pdu_len * 8); + } + + /* Reset the settling trailing samples */ + memset (d_pdu_encoded + d_pdu_len * 8, 0, + d_settling_samples * sizeof(float)); + + /* The new frame now has a bigger size of course*/ + d_pdu_len += d_settling_samples/8; + + /* Start of burst */ + add_sob(nitems_written(0)); } noutput_items = std::max (0, noutput_items); min_available = std::min ((size_t) noutput_items, (d_pdu_len - d_encoded) * 8); - if(d_msb_first){ - map_msb_first(out, min_available*8); - } - else{ - map_lsb_first(out, min_available*8); - } + memcpy(out, d_pdu_encoded + d_encoded*8, min_available * sizeof(float)); d_encoded += min_available/8; /* End of the frame reached */ if(d_encoded == d_pdu_len){ + add_eob(nitems_written(0) + min_available - 1); d_encoded = 0; } diff --git a/lib/upsat_fsk_frame_encoder_impl.h b/lib/upsat_fsk_frame_encoder_impl.h index 0952e0d..fe3abd2 100644 --- a/lib/upsat_fsk_frame_encoder_impl.h +++ b/lib/upsat_fsk_frame_encoder_impl.h @@ -41,23 +41,29 @@ namespace gr const bool d_manchester; const bool d_msb_first; const size_t d_max_pdu_len; + const size_t d_settling_samples; size_t d_encoded; size_t d_pdu_len; whitening d_scrambler; uint8_t *d_pdu; + float *d_pdu_encoded; inline void map_msb_first (float *out, size_t nsamples_out); - inline void map_lsb_first (float *out, size_t nsamples_out); + inline void + add_sob (uint64_t item); + inline void + add_eob (uint64_t item); public: upsat_fsk_frame_encoder_impl (const std::vector& preamble, const std::vector& sync_word, bool append_crc, bool whitening, bool manchester, - bool msb_first); + bool msb_first, + size_t settling_samples); ~upsat_fsk_frame_encoder_impl (); // Where all the action really happens