From ac60e400e22a4352d6eb22d10b47fabf0ddda678 Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Wed, 29 Jan 2020 14:07:33 +0200 Subject: [PATCH 1/2] Add framer block and support variable size frames --- apps/psk_transceiver.grc | 118 +++++++++++++++++++----------- grc/CMakeLists.txt | 1 + grc/tutorial_frame_sync.block.yml | 15 ++-- grc/tutorial_framer.block.yml | 35 +++++++++ include/tutorial/CMakeLists.txt | 1 + include/tutorial/frame_sync.h | 10 ++- include/tutorial/framer.h | 61 +++++++++++++++ lib/CMakeLists.txt | 1 + lib/fec_encoder_impl.cc | 3 +- lib/frame_sync_impl.cc | 11 ++- lib/frame_sync_impl.h | 9 ++- lib/framer_impl.cc | 95 ++++++++++++++++++++++++ lib/framer_impl.h | 46 ++++++++++++ swig/CMakeLists.txt | 5 +- swig/tutorial_swig.i | 3 + 15 files changed, 355 insertions(+), 59 deletions(-) create mode 100644 grc/tutorial_framer.block.yml create mode 100644 include/tutorial/framer.h create mode 100644 lib/framer_impl.cc create mode 100644 lib/framer_impl.h diff --git a/apps/psk_transceiver.grc b/apps/psk_transceiver.grc index 89344c7..0699918 100644 --- a/apps/psk_transceiver.grc +++ b/apps/psk_transceiver.grc @@ -36,7 +36,7 @@ blocks: id: variable parameters: comment: Samples per symbol - value: int(math.log2(variable_constellation_0.arity())) + value: int(math.log2(constellation.arity())) states: bus_sink: false bus_source: false @@ -44,6 +44,24 @@ blocks: coordinate: [1376, 20.0] rotation: 0 state: true +- name: constellation + id: variable_constellation + parameters: + comment: '' + const_points: '[-1-1j, -1+1j, 1+1j, 1-1j]' + dims: '1' + precision: '8' + rot_sym: '4' + soft_dec_lut: None + sym_map: '[0, 1, 3, 2]' + type: bpsk + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1208, 20.0] + rotation: 0 + state: true - name: nfilts id: variable parameters: @@ -92,24 +110,6 @@ blocks: coordinate: [1488, 20.0] rotation: 0 state: true -- name: variable_constellation_0 - id: variable_constellation - parameters: - comment: '' - const_points: '[-1-1j, -1+1j, 1+1j, 1-1j]' - dims: '1' - precision: '8' - rot_sym: '4' - soft_dec_lut: None - sym_map: '[0, 1, 3, 2]' - type: bpsk - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [1208, 20.0] - rotation: 0 - state: true - name: analog_agc2_xx_0 id: analog_agc2_xx parameters: @@ -128,7 +128,7 @@ blocks: max_gain: '65536' maxoutbuf: '0' minoutbuf: '0' - reference: '0.5' + reference: math.sqrt(2)/2 type: complex states: bus_sink: false @@ -217,7 +217,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1072, 172.0] + coordinate: [1216, 172.0] rotation: 0 state: enabled - name: blocks_random_pdu_0 @@ -256,16 +256,18 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [384, 244.0] + coordinate: [384, 252.0] rotation: 0 - state: disabled + state: enabled - name: blocks_tagged_stream_multiply_length_0 id: blocks_tagged_stream_multiply_length parameters: affinity: '' alias: '' c: 8*sps - comment: '' + comment: 'Necessary for proper transmission with + + SDR hardware. Do not care about it!' lengthtagname: packet_len maxoutbuf: '0' minoutbuf: '0' @@ -275,7 +277,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1560, 176.0] + coordinate: [1656, 176.0] rotation: 0 state: enabled - name: blocks_unpack_k_bits_bb_0 @@ -341,7 +343,8 @@ blocks: parameters: affinity: '' alias: '' - comment: '' + comment: "Necessary for proper transmission with\nSDR hardware. It prepends and\ + \ appends some \nzero samples for every frame. Do not care about it!" insert_phasing: 'False' length_tag_name: '"packet_len"' maxoutbuf: '0' @@ -354,7 +357,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1808, 156.0] + coordinate: [1896, 156.0] rotation: 0 state: enabled - name: digital_constellation_receiver_cb_0 @@ -364,7 +367,7 @@ blocks: alias: '' comment: "Performs frequency synchronization\n (stops the rotation of PSK symbols)\n\ and demaps the received constellation\n points into bits" - constellation: variable_constellation_0 + constellation: constellation fmax: '0.25' fmin: '-0.25' loop_bw: 2.0 * math.pi/100.0 @@ -643,7 +646,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [2056, 48.0] + coordinate: [2128, 48.0] rotation: 0 state: true - name: qtgui_freq_sink_x_0_0 @@ -723,7 +726,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1576, 296.0] + coordinate: [1568, 320.0] rotation: 180 state: true - name: qtgui_time_sink_x_0 @@ -828,8 +831,16 @@ blocks: parameters: affinity: '' alias: '' - comment: '' - constellation: variable_constellation_0 + comment: 'There is a bug with the tag propagation, + + so I rebuilt this block. It exactly the same + + with the GNU Radio but deals properly + + with the burst tag propagation needed + + for proper transmission via SDR hardware' + constellation: constellation differential: 'True' excess_bw: excess_bw maxoutbuf: '0' @@ -839,7 +850,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1288, 148.0] + coordinate: [1416, 148.0] rotation: 0 state: true - name: tutorial_deinterleaver_0 @@ -887,7 +898,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [720, 172.0] + coordinate: [704, 172.0] rotation: 0 state: true - name: tutorial_frame_sync_0 @@ -895,20 +906,44 @@ blocks: parameters: affinity: '' alias: '' - comment: '' - frame_len: '128' + comment: 'Internally we have an enum. For 0 for BPSK, 1 for QPSK. + + Using the bits per symbol - 1 we can select automatically + + the modulation.' maxoutbuf: '0' minoutbuf: '0' - preamble: '170' + mod: bits_per_symbol - 1 + preamble: '0xAA' preamble_len: '64' - sync_word: '[88, 154]' + sync_word: '[0x58, 0x9A]' states: bus_sink: false bus_source: false bus_structure: null - coordinate: [536, 740.0] + coordinate: [544, 740.0] rotation: 0 state: true +- name: tutorial_framer_0 + id: tutorial_framer + parameters: + affinity: '' + alias: '' + comment: 'Use the best preamble, sync word and their + + length to win the contest!' + maxoutbuf: '0' + minoutbuf: '0' + preamble: '0xAA' + preamble_len: '64' + sync_word: '[0x58, 0x9A]' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1000, 156.0] + rotation: 0 + state: enabled - name: tutorial_interleaver_0 id: tutorial_interleaver parameters: @@ -922,7 +957,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [904, 172.0] + coordinate: [864, 172.0] rotation: 0 state: true @@ -954,7 +989,8 @@ connections: - [tutorial_fec_decoder_0, pdu_out, digital_crc32_async_bb_0_0, in] - [tutorial_fec_encoder_0, pdu_out, tutorial_interleaver_0, pdu_in] - [tutorial_frame_sync_0, pdu, tutorial_deinterleaver_0, pdu_in] -- [tutorial_interleaver_0, pdu_out, blocks_pdu_to_tagged_stream_0, pdus] +- [tutorial_framer_0, frame, blocks_pdu_to_tagged_stream_0, pdus] +- [tutorial_interleaver_0, pdu_out, tutorial_framer_0, pdu] metadata: file_format: 1 diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index f825975..bc635cd 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -25,6 +25,7 @@ install(FILES tutorial_fec_decoder.block.yml tutorial_fec_encoder.block.yml tutorial_frame_sync.block.yml + tutorial_framer.block.yml tutorial_interleaver.block.yml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/tutorial_frame_sync.block.yml b/grc/tutorial_frame_sync.block.yml index 0b0ef83..deeab54 100644 --- a/grc/tutorial_frame_sync.block.yml +++ b/grc/tutorial_frame_sync.block.yml @@ -4,13 +4,13 @@ category: '[tutorial]' templates: imports: import tutorial - make: tutorial.frame_sync(${preamble}, ${preamble_len}, ${&sync_word}, ${frame_len}) + make: tutorial.frame_sync(${preamble}, ${preamble_len}, ${sync_word}, ${mod}) parameters: - id: preamble label: Preamble dtype: raw - default: 0xAA + default: '0xAA' - id: preamble_len label: Preamble Length @@ -20,12 +20,14 @@ parameters: - id: sync_word label: Synchronization Word dtype: raw - default: [0x58, 0x9A] + default: '[0x58, 0x9A]' -- id: frame_len - label: Frame Length +- id: mod + label: Modulation dtype: int - default: 128 + options: [0, 1] + option_labels: [BPSK, QPSK] + default: 0 inputs: - label: in @@ -36,5 +38,4 @@ outputs: - id: pdu domain: message - file_format: 1 diff --git a/grc/tutorial_framer.block.yml b/grc/tutorial_framer.block.yml new file mode 100644 index 0000000..0b81b77 --- /dev/null +++ b/grc/tutorial_framer.block.yml @@ -0,0 +1,35 @@ +id: tutorial_framer +label: Framer +category: '[tutorial]' + +templates: + imports: import tutorial + make: tutorial.framer(${preamble}, ${preamble_len}, ${sync_word}) + +parameters: +- id: preamble + label: Preamble + dtype: raw + default: '0xAA' + +- id: preamble_len + label: Preamble Length + dtype: int + default: 64 + +- id: sync_word + label: Synchronization Word + dtype: raw + default: '[0x58, 0x9A]' + +inputs: +- id: pdu + domain: message + +outputs: +- id: frame + domain: message + + +file_format: 1 + diff --git a/include/tutorial/CMakeLists.txt b/include/tutorial/CMakeLists.txt index 0326c1f..4ff3dca 100644 --- a/include/tutorial/CMakeLists.txt +++ b/include/tutorial/CMakeLists.txt @@ -28,6 +28,7 @@ install(FILES fec_decoder.h fec_encoder.h frame_sync.h + framer.h interleaver.h DESTINATION include/tutorial ) diff --git a/include/tutorial/frame_sync.h b/include/tutorial/frame_sync.h index d1a4072..5ddb86b 100644 --- a/include/tutorial/frame_sync.h +++ b/include/tutorial/frame_sync.h @@ -31,8 +31,11 @@ namespace tutorial { * \brief This block searches for a valid preamble. Using then the * synchronization word it extracts the received frame. * - * The frame sync block supports only fixed sized frames, with a known - * frame length. + * The based on the frame length field it extracts the rest of the payload. + * + * The block produces a PMT pair message, compliant with the pair messages + * GNU Radio uses, containing only the payload of the + * frame (without preamble, sync word, length field) * \ingroup tutorial * */ @@ -49,7 +52,8 @@ public: * creating new instances. */ static sptr make(uint8_t preamble, uint8_t preamble_len, - const std::vector &sync_word, size_t frame_len); + const std::vector &sync_word, + int mod); }; } // namespace tutorial diff --git a/include/tutorial/framer.h b/include/tutorial/framer.h new file mode 100644 index 0000000..5717312 --- /dev/null +++ b/include/tutorial/framer.h @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * gr-tutorial: Useful blocks for SDR and GNU Radio learning + * + * Copyright (C) 2019, 2020 Manolis Surligas + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef INCLUDED_TUTORIAL_FRAMER_H +#define INCLUDED_TUTORIAL_FRAMER_H + +#include +#include + +namespace gr { +namespace tutorial { + +/*! + * \brief Constructs a frame with the received payload + * + * The frame has the following format + * ------------------------------------------------------------------------ + * | preamble | sync word | frame length (uint16_t) | payload | + * ------------------------------------------------------------------------ + * + * \ingroup tutorial + * + */ +class TUTORIAL_API framer : virtual public gr::block { +public: + typedef boost::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of tutorial::framer. + * + * To avoid accidental use of raw pointers, tutorial::framer's + * constructor is in a private implementation + * class. tutorial::framer::make is the public interface for + * creating new instances. + */ + static sptr make(uint8_t preamble, size_t preamble_len, + const std::vector &sync_word); +}; + +} // namespace tutorial +} // namespace gr + +#endif /* INCLUDED_TUTORIAL_FRAMER_H */ + diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 597439a..0a5054c 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -29,6 +29,7 @@ list(APPEND tutorial_sources fec_decoder_impl.cc fec_encoder_impl.cc frame_sync_impl.cc + framer_impl.cc interleaver_impl.cc ) diff --git a/lib/fec_encoder_impl.cc b/lib/fec_encoder_impl.cc index efade1b..cceccfb 100644 --- a/lib/fec_encoder_impl.cc +++ b/lib/fec_encoder_impl.cc @@ -48,7 +48,8 @@ fec_encoder_impl::fec_encoder_impl(int type) message_port_register_in(pmt::mp("pdu_in")); message_port_register_out(pmt::mp("pdu_out")); - /* Register the message handler. For every message received in the input + /* + * Register the message handler. For every message received in the input * message port it will be called automatically. */ set_msg_handler(pmt::mp("pdu_in"), diff --git a/lib/frame_sync_impl.cc b/lib/frame_sync_impl.cc index 0b15d17..2b4d24e 100644 --- a/lib/frame_sync_impl.cc +++ b/lib/frame_sync_impl.cc @@ -30,10 +30,11 @@ namespace tutorial { frame_sync::sptr frame_sync::make(uint8_t preamble, uint8_t preamble_len, - const std::vector &sync_word, size_t frame_len) + const std::vector &sync_word, + int mod) { return gnuradio::get_initial_sptr - (new frame_sync_impl(preamble, preamble_len, sync_word, frame_len)); + (new frame_sync_impl(preamble, preamble_len, sync_word, mod)); } @@ -41,10 +42,12 @@ frame_sync::make(uint8_t preamble, uint8_t preamble_len, * The private constructor */ frame_sync_impl::frame_sync_impl(uint8_t preamble, uint8_t preamble_len, - const std::vector &sync_word, size_t frame_len) + const std::vector &sync_word, + int mod) : gr::sync_block("frame_sync", gr::io_signature::make(1, 1, sizeof(uint8_t)), - gr::io_signature::make(0, 0, 0)) + gr::io_signature::make(0, 0, 0)), + d_mod((mod_t)mod) { message_port_register_out(pmt::mp("pdu")); } diff --git a/lib/frame_sync_impl.h b/lib/frame_sync_impl.h index b0231fb..a426ce9 100644 --- a/lib/frame_sync_impl.h +++ b/lib/frame_sync_impl.h @@ -28,11 +28,16 @@ namespace tutorial { class frame_sync_impl : public frame_sync { private: - // Nothing to declare in this block. + typedef enum { + BPSK, + QPSK + } mod_t; + const mod_t d_mod; public: frame_sync_impl(uint8_t preamble, uint8_t preamble_len, - const std::vector &sync_word, size_t frame_len); + const std::vector &sync_word, + int mod); ~frame_sync_impl(); // Where all the action really happens diff --git a/lib/framer_impl.cc b/lib/framer_impl.cc new file mode 100644 index 0000000..88455a3 --- /dev/null +++ b/lib/framer_impl.cc @@ -0,0 +1,95 @@ +/* -*- c++ -*- */ +/* + * gr-tutorial: Useful blocks for SDR and GNU Radio learning + * + * Copyright (C) 2019, 2020 Manolis Surligas + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "framer_impl.h" + +namespace gr { +namespace tutorial { + +framer::sptr +framer::make(uint8_t preamble, size_t preamble_len, + const std::vector &sync_word) +{ + return gnuradio::get_initial_sptr( + new framer_impl(preamble, preamble_len, sync_word)); +} + +/* + * The private constructor + */ +framer_impl::framer_impl(uint8_t preamble, size_t preamble_len, + const std::vector &sync_word) : + gr::block("framer", gr::io_signature::make(0, 0, 0), + gr::io_signature::make(0, 0, 0)) +{ + message_port_register_in(pmt::mp("pdu")); + message_port_register_out(pmt::mp("frame")); + + /* + * Register the message handler. For every message received in the input + * message port it will be called automatically. + */ + set_msg_handler(pmt::mp("pdu"), + boost::bind(&framer_impl::construct, this, _1)); +} + +void +framer_impl::construct(pmt::pmt_t m) +{ + /* Extract the bytes of the PDU. GNU Radio handles PDUs in pairs. + * The first element of the pair contains metadata associated with the + * PDU, whereas the second element of the pair is a pmt with a u8 vector + * containing the raw bytes. Below there is an example how to get the + * PDU raw pointer and the length of the frame in bytes that points to + */ + pmt::pmt_t meta(pmt::car(m)); + pmt::pmt_t bytes(pmt::cdr(m)); + /* Access the raw bytes of the PDU */ + size_t pdu_len; + const uint8_t *bytes_in = pmt::u8vector_elements(bytes, pdu_len); + + /* + * TODO: Do processing + */ + /* + * FIXME: This just copies the input to the output. It is just for testing + * purposes. + * NOTE: Obey the pair scheme that GNU Radio uses otherwise following + * blocks will not work. In your case if you do not have any associated + * metadata, place just pmt::PMT_NIL on the first element of the pair + */ + message_port_pub(pmt::mp("frame"), pmt::cons(pmt::PMT_NIL, bytes)); +} + +/* + * Our virtual destructor. + */ +framer_impl::~framer_impl() +{ +} + +} /* namespace tutorial */ +} /* namespace gr */ + diff --git a/lib/framer_impl.h b/lib/framer_impl.h new file mode 100644 index 0000000..da61191 --- /dev/null +++ b/lib/framer_impl.h @@ -0,0 +1,46 @@ +/* -*- c++ -*- */ +/* + * gr-tutorial: Useful blocks for SDR and GNU Radio learning + * + * Copyright (C) 2019, 2020 Manolis Surligas + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef INCLUDED_TUTORIAL_FRAMER_IMPL_H +#define INCLUDED_TUTORIAL_FRAMER_IMPL_H + +#include + +namespace gr { +namespace tutorial { + +class framer_impl : public framer { +private: + void + construct(pmt::pmt_t m); + +public: + framer_impl(uint8_t preamble, size_t preamble_len, + const std::vector &sync_word); + ~framer_impl(); + + +}; + +} // namespace tutorial +} // namespace gr + +#endif /* INCLUDED_TUTORIAL_FRAMER_IMPL_H */ + diff --git a/swig/CMakeLists.txt b/swig/CMakeLists.txt index 5ae654d..865f39e 100644 --- a/swig/CMakeLists.txt +++ b/swig/CMakeLists.txt @@ -40,7 +40,10 @@ include(GrPython) ######################################################################## # Setup swig generation ######################################################################## -set(GR_SWIG_INCLUDE_DIRS $) +set(GR_SWIG_INCLUDE_DIRS + $ + $) + set(GR_SWIG_TARGET_DEPS gnuradio::runtime_swig) set(GR_SWIG_LIBRARIES gnuradio-tutorial) diff --git a/swig/tutorial_swig.i b/swig/tutorial_swig.i index ebbfa2a..b7f8b63 100644 --- a/swig/tutorial_swig.i +++ b/swig/tutorial_swig.i @@ -13,6 +13,7 @@ #include "tutorial/deinterleaver.h" #include "tutorial/fec_encoder.h" #include "tutorial/frame_sync.h" +#include "tutorial/framer.h" %} %include "tutorial/complex_clamp.h" @@ -25,3 +26,5 @@ GR_SWIG_BLOCK_MAGIC2(tutorial, deinterleaver); GR_SWIG_BLOCK_MAGIC2(tutorial, fec_encoder); %include "tutorial/frame_sync.h" GR_SWIG_BLOCK_MAGIC2(tutorial, frame_sync); +%include "tutorial/framer.h" +GR_SWIG_BLOCK_MAGIC2(tutorial, framer); -- GitLab From 92704c0e9f2767f8b9d91de6b0ffd464c310edda Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Thu, 30 Jan 2020 01:44:50 +0200 Subject: [PATCH 2/2] Add shift register class --- apps/psk_transceiver.grc | 24 +++- include/tutorial/CMakeLists.txt | 1 + include/tutorial/shift_reg.h | 118 ++++++++++++++++ lib/CMakeLists.txt | 1 + lib/shift_reg.cc | 229 ++++++++++++++++++++++++++++++++ 5 files changed, 367 insertions(+), 6 deletions(-) create mode 100644 include/tutorial/shift_reg.h create mode 100644 lib/shift_reg.cc diff --git a/apps/psk_transceiver.grc b/apps/psk_transceiver.grc index 0699918..d380aae 100644 --- a/apps/psk_transceiver.grc +++ b/apps/psk_transceiver.grc @@ -172,7 +172,9 @@ blocks: parameters: affinity: '' alias: '' - comment: '' + comment: 'This triggers the random PDU Generator + + to create a PDU' dist: blocks.STROBE_UNIFORM maxoutbuf: '0' mean: '100' @@ -183,7 +185,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [72, 148.0] + coordinate: [16, 148.0] rotation: 0 state: true - name: blocks_null_sink_0 @@ -225,7 +227,13 @@ blocks: parameters: affinity: '' alias: '' - comment: '' + comment: 'To use a specific size just set the minimum and + + maximum bytes to the same desired value. + + Do not forget that the CRC32 adds 4 bytes + + and that FEC will also add extra bits' length_modulo: '2' mask: '0xFF' maxoutbuf: '0' @@ -236,7 +244,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [336, 148.0] + coordinate: [248, 148.0] rotation: 0 state: true - name: blocks_socket_pdu_0 @@ -244,7 +252,11 @@ blocks: parameters: affinity: '' alias: '' - comment: '' + comment: 'You can receive also UDP packets. + + This will be used for the contest, + + but you can also use it during your tests' host: '' maxoutbuf: '0' minoutbuf: '0' @@ -256,7 +268,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [384, 252.0] + coordinate: [344, 324.0] rotation: 0 state: enabled - name: blocks_tagged_stream_multiply_length_0 diff --git a/include/tutorial/CMakeLists.txt b/include/tutorial/CMakeLists.txt index 4ff3dca..df00045 100644 --- a/include/tutorial/CMakeLists.txt +++ b/include/tutorial/CMakeLists.txt @@ -30,5 +30,6 @@ install(FILES frame_sync.h framer.h interleaver.h + shift_reg.h DESTINATION include/tutorial ) diff --git a/include/tutorial/shift_reg.h b/include/tutorial/shift_reg.h new file mode 100644 index 0000000..e206f2d --- /dev/null +++ b/include/tutorial/shift_reg.h @@ -0,0 +1,118 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2018, Libre Space Foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +/* + * gr-tutorial: Useful blocks for SDR and GNU Radio learning + * + * Copyright (C) 2019, 2020 Manolis Surligas + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef INCLUDED_SATNOGS_SHIFT_REG_H +#define INCLUDED_SATNOGS_SHIFT_REG_H + +#include +#include +#include + +namespace gr { +namespace tutorial { + +/*! + * \brief Implements a bit shift register + * + */ +class TUTORIAL_API shift_reg { +public: + shift_reg(size_t len); + ~shift_reg(); + + void + reset(); + + void + set(); + + size_t + len() const; + + size_t + size() const; + + size_t + count(); + + shift_reg + operator|(const shift_reg &rhs); + + shift_reg + operator&(const shift_reg &rhs); + + shift_reg + operator^(const shift_reg &rhs); + + shift_reg & + operator>>=(bool bit); + + bool & + operator[](size_t pos); + + bool + operator[](size_t pos) const; + + shift_reg & + operator<<=(bool bit); + + void + push_front(bool bit); + + void + push_back(bool bit); + + bool + front(); + + bool + back(); + + friend std::ostream & + operator<<(std::ostream &os, const shift_reg ®); + +private: + const size_t d_len; + std::deque d_reg; +}; + +} // namespace tutorial +} // namespace gr + +#endif /* INCLUDED_SATNOGS_SHIFT_REG_H */ + diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 0a5054c..46ca04f 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -31,6 +31,7 @@ list(APPEND tutorial_sources frame_sync_impl.cc framer_impl.cc interleaver_impl.cc + shift_reg.cc ) set(tutorial_sources "${tutorial_sources}" PARENT_SCOPE) diff --git a/lib/shift_reg.cc b/lib/shift_reg.cc new file mode 100644 index 0000000..1df64f5 --- /dev/null +++ b/lib/shift_reg.cc @@ -0,0 +1,229 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2018, Libre Space Foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* + * gr-tutorial: Useful blocks for SDR and GNU Radio learning + * + * Copyright (C) 2019, 2020 Manolis Surligas + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +namespace gr { +namespace tutorial { + +/** + * Creates a new shift register + * @param len the number of the memory stages + */ +shift_reg::shift_reg(size_t len) + : d_len(len), + d_reg(len, 0) +{ +} + +shift_reg::~shift_reg() +{ +} + +/** + * Sets all the memory stages to 0 + */ +void +shift_reg::reset() +{ + for (size_t i = 0; i < d_len; i++) { + d_reg[i] = 0; + } +} + +/** + * Sets all the memory stages to 1 + */ +void +shift_reg::set() +{ + for (size_t i = 0; i < d_len; i++) { + d_reg[i] = 1; + } +} + +/** + * + * @return the number of the memory stages of the shift register + */ +size_t +shift_reg::len() const +{ + return d_len; +} + +/** + * + * @return the number of the memory stages of the shift register + */ +size_t +shift_reg::size() const +{ + return d_len; +} + +/** + * + * @return the number of 1 bits + */ +size_t +shift_reg::count() +{ + size_t cnt = 0; + for (bool i : d_reg) { + cnt += i; + } + return cnt; +} + +shift_reg +shift_reg::operator | (const shift_reg &rhs) +{ + shift_reg ret(d_len); + for (size_t i = 0; i < d_len; i++) { + ret[i] = d_reg[i] | rhs[i]; + } + return ret; +} + +shift_reg +shift_reg::operator & (const shift_reg &rhs) +{ + shift_reg ret(d_len); + for (size_t i = 0; i < d_len; i++) { + ret[i] = d_reg[i] & rhs[i]; + } + return ret; +} + +shift_reg +shift_reg::operator ^ (const shift_reg &rhs) +{ + shift_reg ret(d_len); + for (size_t i = 0; i < d_len; i++) { + ret[i] = d_reg[i] ^ rhs[i]; + } + return ret; +} + +shift_reg & +shift_reg::operator >>= (bool bit) +{ + push_front(bit); + return *this; +} + +bool & +shift_reg::operator [](size_t pos) +{ + return d_reg[pos]; +} + +bool +shift_reg::operator[](size_t pos) const +{ + return d_reg[pos]; +} + +shift_reg & +shift_reg::operator <<= (bool bit) +{ + push_back(bit); + return *this; +} + +/** + * Push at the front a new value and pops from the back + * @param bit the new value + */ +void +shift_reg::push_front(bool bit) +{ + d_reg.pop_back(); + d_reg.push_front(bit); +} + +/** + * Push at the back a new value and pops from the front + * @param bit the new value + */ +void +shift_reg::push_back(bool bit) +{ + d_reg.pop_front(); + d_reg.push_back(bit); +} + +/** + * + * @return the first element in the queue from right to left + */ +bool +shift_reg::front() +{ + return d_reg.front(); +} + +/** + * + * @return the last element in the queue from right to left + */ +bool +shift_reg::back() +{ + return d_reg.back(); +} + +std::ostream & +operator<<(std::ostream &os, const shift_reg ®) +{ + for (bool bit : reg.d_reg) { + os << " " << bit; + } + return os; +} + +} /* namespace satnogs */ +} /* namespace gr */ + -- GitLab