diff --git a/software/gr-caribouLite/grc/caribouLite_caribouLiteSource.block.yml b/software/gr-caribouLite/grc/caribouLite_caribouLiteSource.block.yml index a2e258c..236d391 100644 --- a/software/gr-caribouLite/grc/caribouLite_caribouLiteSource.block.yml +++ b/software/gr-caribouLite/grc/caribouLite_caribouLiteSource.block.yml @@ -1,7 +1,7 @@ id: caribouLite_caribouLiteSource label: CaribouLite Source category: '[caribouLite]' -flags: throttle +flags: [python,cpp,throttle] templates: imports: @@ -9,13 +9,6 @@ templates: make: caribouLite.caribouLiteSource(${channel}, ${enable_agc}, ${rx_gain}, ${rx_bw}, ${sample_rate}, ${freq}) - -# Make one 'parameters' list entry for every parameter you want settable from the GUI. -# Keys include: -# * id (makes the value accessible as keyname, e.g. in the make entry) -# * label (label shown in the GUI) -# * dtype (e.g. int, float, complex, byte, short, xxx_vector, ...) -# * default parameters: - id: channel label: S1G(0) or HiF(1) @@ -46,24 +39,22 @@ parameters: label: Frequency [Hz] dtype: float default: 900000000.0 + +cpp_templates: + includes: ['#include '] + declarations: 'caribouLite::caribouLiteSource::sptr ${id};' + make: 'this->${id} = caribouLite::caribouLiteSource::make(${channel}, ${enable_agc}, ${rx_gain}, ${rx_bw}, ${sample_rate}, ${freq});' + packages: ['gnuradio-caribouLite'] + link: ['gnuradio::gnuradio-caribouLite'] + translations: + 'False': 'false' + 'True': 'true' + \[: '{' + \]: '}' - -# Make one 'inputs' list entry per input and one 'outputs' list entry per output. -# Keys include: -# * label (an identifier for the GUI) -# * domain (optional - stream or message. Default is stream) -# * dtype (e.g. int, float, complex, byte, short, xxx_vector, ...) -# * vlen (optional - data stream vector length. Default is 1) -# * optional (optional - set to 1 for optional inputs. Default is 0) -inputs: - - outputs: - label: samples domain: stream dtype: complex - -# 'file_format' specifies the version of the GRC yml format used in the file -# and should usually not be changed. file_format: 1 diff --git a/software/gr-caribouLite/lib/caribouLiteSource_impl.cc b/software/gr-caribouLite/lib/caribouLiteSource_impl.cc index c789362..050f917 100644 --- a/software/gr-caribouLite/lib/caribouLiteSource_impl.cc +++ b/software/gr-caribouLite/lib/caribouLiteSource_impl.cc @@ -40,40 +40,33 @@ namespace gr { } - // private constructor + // public constructor //------------------------------------------------------------------------------------------------------------- caribouLiteSource_impl::caribouLiteSource_impl(int channel, bool enable_agc, float rx_gain, float rx_bw, float sample_rate, float freq) : gr::sync_block("caribouLiteSource", gr::io_signature::make(0, 0, 0), gr::io_signature::make(1 /* min outputs */, 1 /*max outputs */, sizeof(output_type))) { - _rx_queue = NULL; + detectBoard(); + _channel = (CaribouLiteRadio::RadioType)channel; _enable_agc = enable_agc; _rx_gain = rx_gain; _rx_bw = rx_bw; _sample_rate = sample_rate; _frequency = freq; - detectBoard(); CaribouLite &cl = CaribouLite::GetInstance(); _cl = &cl; _radio = cl.GetRadioChannel(_channel); _mtu_size = _radio->GetNativeMtuSample(); - _rx_queue = new circular_buffer(_mtu_size * NUM_NATIVE_MTUS_PER_QUEUE, - USE_ASYNC_OVERRIDE_WRITES, - USE_ASYNC_BLOCK_READS); - // setup parameters _radio->SetRxGain(rx_gain); _radio->SetAgc(enable_agc); _radio->SetRxBandwidth(rx_bw); _radio->SetRxSampleRate(sample_rate); _radio->SetFrequency(freq); - _radio->StartReceiving([this](CaribouLiteRadio* radio, const std::complex* samples, CaribouLiteMeta* sync, size_t num_samples) { - receivedSamples(radio, samples, sync, num_samples); - }); } // virtual destructor @@ -81,24 +74,15 @@ namespace gr { caribouLiteSource_impl::~caribouLiteSource_impl() { _radio->StopReceiving(); - if (_rx_queue) delete _rx_queue; - } - - // Receive samples callback - //------------------------------------------------------------------------------------------------------------- - void caribouLiteSource_impl::receivedSamples(CaribouLiteRadio* radio, const std::complex* samples, CaribouLiteMeta* sync, size_t num_samples) - { - //std::cout << "Radio: " << radio->GetRadioName() << " Received " << std::dec << num_samples << " samples" << std::endl; - _rx_queue->put(static_cast(samples), num_samples); } //------------------------------------------------------------------------------------------------------------- - int caribouLiteSource_impl::work( int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) + int caribouLiteSource_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { auto out = static_cast(output_items[0]); - size_t num_read = _rx_queue->get(out, noutput_items); + _radio->ReadSamples(out, static_cast(noutput_items)); return noutput_items; } diff --git a/software/gr-caribouLite/lib/caribouLiteSource_impl.h b/software/gr-caribouLite/lib/caribouLiteSource_impl.h index 5d77686..17a6a97 100644 --- a/software/gr-caribouLite/lib/caribouLiteSource_impl.h +++ b/software/gr-caribouLite/lib/caribouLiteSource_impl.h @@ -10,16 +10,17 @@ #include #include -#include "circular_buffer.h" namespace gr { namespace caribouLite { + void detectBoard(); + class caribouLiteSource_impl : public caribouLiteSource { private: - CaribouLiteRadio::RadioType _channel; + CaribouLiteRadio::RadioType _channel; //RadioType, NOT frequency bool _enable_agc; float _rx_gain; float _rx_bw; @@ -29,10 +30,6 @@ namespace gr CaribouLite* _cl; CaribouLiteRadio *_radio; - circular_buffer *_rx_queue; - - private: - void receivedSamples(CaribouLiteRadio* radio, const std::complex* samples, CaribouLiteMeta* sync, size_t num_samples); public: caribouLiteSource_impl(int channel, bool enable_agc, float rx_gain, float rx_bw, float sample_rate, float freq); diff --git a/software/gr-caribouLite/lib/circular_buffer.h b/software/gr-caribouLite/lib/circular_buffer.h deleted file mode 100644 index b5b7582..0000000 --- a/software/gr-caribouLite/lib/circular_buffer.h +++ /dev/null @@ -1,165 +0,0 @@ -#ifndef __CIRC_BUFFER_H__ -#define __CIRC_BUFFER_H__ - -#include -#include -#include -#include -#include -#include - -#define IS_POWER_OF_2(x) (!((x) == 0) && !((x) & ((x) - 1))) -#define MIN(x,y) ((x)>(y)?(y):(x)) - - -template -class circular_buffer { -public: - circular_buffer(size_t size, bool override_write = true, bool block_read = true) - { - max_size_ = size; - if (!IS_POWER_OF_2(max_size_)) - { - max_size_ = next_power_of_2(max_size_); - } - buf_ = new T[max_size_]; - override_write_ = override_write; - block_read_ = block_read; - } - - ~circular_buffer() - { - std::unique_lock lock(mutex_); - delete []buf_; - } - - size_t put(const T *data, size_t length) - { - std::lock_guard lock(mutex_); - - if ((max_size_ - size()) < length && override_write_) - { - // pop the amount of data the is needed - tail_ += length - (max_size_ - size()); - } - - size_t len = MIN(length, max_size_ - head_ + tail_); - auto l = MIN(len, max_size_ - (head_ & (max_size_ - 1))); - - memcpy(buf_ + (head_ & (max_size_ - 1)), data, l * sizeof(T)); - memcpy(buf_, data + l, (len - l) * sizeof(T)); - - head_ += len; - - if (block_read_) - { - cond_var_.notify_one(); - } - - return len; - } - - size_t get(T *data, size_t length, int timeout_us = 100000) - { - std::unique_lock lock(mutex_); - - if (block_read_) - { - cond_var_.wait_for(lock, std::chrono::microseconds(timeout_us), [&]() - { - // Acquire the lock only if - // we got enough items - return size() >= length; - }); - - if (size() < length) - { - return 0; - } - } - - size_t len = MIN(length, head_ - tail_); - auto l = MIN(len, max_size_ - (tail_ & (max_size_ - 1))); - - if (data != NULL) - { - memcpy(data, buf_ + (tail_ & (max_size_ - 1)), l * sizeof(T)); - memcpy(data + l, buf_, (len - l) * sizeof(T)); - } - tail_ += len; - return len; - } - - void put(T item) - { - put(&item, 1); - } - - T get() - { - T item; - get(&item, 1); - return item; - } - - void reset() - { - std::unique_lock lock(mutex_); - head_ = tail_ = 0; - } - - inline bool empty() - { - return head_ == tail_; - } - - inline bool full() - { - return size() == capacity(); - } - - inline size_t capacity() const - { - return max_size_; - } - - size_t size() - { - return (head_ - tail_); - } - - void print_buffer() - { - std::unique_lock lock(mutex_); - size_t t = tail_; - int i = 0; - while (t < head_) - { - printf("%d => %d\n", i++, (int)buf_[t++&(max_size_-1)]); - } - } - -private: - uint32_t next_power_of_2 (uint32_t x) - { - uint32_t power = 1; - while(power < x) - { - power <<= 1; - } - return power; - } - -private: - std::mutex mutex_; - std::condition_variable cond_var_; - - T* buf_; - size_t head_ = 0; - size_t tail_ = 0; - size_t max_size_; - bool override_write_; - bool block_read_; -}; - -#endif \ No newline at end of file