diff --git a/apps/psk_transceiver.grc b/apps/psk_transceiver.grc index 89344c77bca71176dd0bc92dde6412abeaebe3a9..d380aaec1ed79f0d150b283c701fa321133ba73b 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 @@ -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 @@ -217,7 +219,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 @@ -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,16 +268,18 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [384, 244.0] + coordinate: [344, 324.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 +289,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 +355,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 +369,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 +379,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 +658,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 +738,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 +843,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 +862,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 +910,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 +918,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 +969,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 +1001,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 f825975b62b7b42b0e2dadcc636d580ac49e26ad..bc635cda1a2d40b38ce806a99bd83a0bbeff5d76 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 0b0ef8399b5b602d7a98e951aad097f4160bd3df..deeab542b9f01b5b6ef1d4801c48d811bb4cc506 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 0000000000000000000000000000000000000000..0b81b772f2e299b738b09eb5bd9b2030af958f53 --- /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 0326c1f478e2691ee57cad96915aee199091713a..df000453d8086f8ce9a2a000dee8134286cf724b 100644 --- a/include/tutorial/CMakeLists.txt +++ b/include/tutorial/CMakeLists.txt @@ -28,6 +28,8 @@ install(FILES fec_decoder.h fec_encoder.h frame_sync.h + framer.h interleaver.h + shift_reg.h DESTINATION include/tutorial ) diff --git a/include/tutorial/frame_sync.h b/include/tutorial/frame_sync.h index d1a40728a7352aedbcc8a20b2c19534aefc26a61..5ddb86bcdf806ca77bf133ce6076342e3a4989c5 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 0000000000000000000000000000000000000000..5717312ac0a168ec3eb21e14a8f8d89874cecd83 --- /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/include/tutorial/shift_reg.h b/include/tutorial/shift_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..e206f2d47a5994ef151c91e68e45978d7e11f1cb --- /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 597439aa1454dd8b6d44d3876a9790a990d8d7ca..46ca04f7b030f5e661f551e2e4bc321632111e5e 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -29,7 +29,9 @@ list(APPEND tutorial_sources fec_decoder_impl.cc fec_encoder_impl.cc frame_sync_impl.cc + framer_impl.cc interleaver_impl.cc + shift_reg.cc ) set(tutorial_sources "${tutorial_sources}" PARENT_SCOPE) diff --git a/lib/fec_encoder_impl.cc b/lib/fec_encoder_impl.cc index efade1bbef8a49f9c0ffc480a8cbfa0c6cd24ef7..cceccfba7043b0ab7c4e6c3cbe1962bd24247308 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 0b15d174a5311581ea787aa2286ad6d77fc3f3f6..2b4d24ed7b91943040bc35b2998dd61bb5de84df 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 b0231fb9f13ebe9a44928d171da1d902c120b5c3..a426ce90a13ff1d2a5b2fc1daaaabaa935c8e262 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 0000000000000000000000000000000000000000..88455a3845ad2d425dead97c2584c36e238847b7 --- /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 0000000000000000000000000000000000000000..da61191b98820216178da78234654e3fdd94d90f --- /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/lib/shift_reg.cc b/lib/shift_reg.cc new file mode 100644 index 0000000000000000000000000000000000000000..1df64f53fb02370f5bb25731f65c1dbbde6bbf1c --- /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 */ + diff --git a/swig/CMakeLists.txt b/swig/CMakeLists.txt index 5ae654d7995c927cc5d14d4e256093318815f1d5..865f39e0637521a1433d221ae313ef1c6a632732 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 ebbfa2a8ea94ea29c8f3b6625a8a7afa506b5412..b7f8b630f252e28dddf2dc74176faac36f89dc78 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);