kopia lustrzana https://github.com/cariboulabs/cariboulite
Merge branch 'fixing_gr_cariboulite'
commit
f8e06e1127
|
@ -0,0 +1,144 @@
|
||||||
|
options:
|
||||||
|
parameters:
|
||||||
|
author: Alon and David
|
||||||
|
catch_exceptions: 'True'
|
||||||
|
category: '[GRC Hier Blocks]'
|
||||||
|
cmake_opt: ''
|
||||||
|
comment: ''
|
||||||
|
copyright: ''
|
||||||
|
description: ''
|
||||||
|
gen_cmake: 'On'
|
||||||
|
gen_linking: dynamic
|
||||||
|
generate_options: qt_gui
|
||||||
|
hier_block_src_path: '.:'
|
||||||
|
id: cariboulite_source_test
|
||||||
|
max_nouts: '0'
|
||||||
|
output_language: python
|
||||||
|
placement: (0,0)
|
||||||
|
qt_qss_theme: ''
|
||||||
|
realtime_scheduling: ''
|
||||||
|
run: 'True'
|
||||||
|
run_command: '{python} -u {filename}'
|
||||||
|
run_options: prompt
|
||||||
|
sizing_mode: fixed
|
||||||
|
thread_safe_setters: ''
|
||||||
|
title: ''
|
||||||
|
window_size: ''
|
||||||
|
states:
|
||||||
|
bus_sink: false
|
||||||
|
bus_source: false
|
||||||
|
bus_structure: null
|
||||||
|
coordinate: [16, 4]
|
||||||
|
rotation: 0
|
||||||
|
state: enabled
|
||||||
|
|
||||||
|
blocks:
|
||||||
|
- name: caribouLite_caribouLiteSource_0
|
||||||
|
id: caribouLite_caribouLiteSource
|
||||||
|
parameters:
|
||||||
|
affinity: ''
|
||||||
|
alias: ''
|
||||||
|
channel: '0'
|
||||||
|
comment: ''
|
||||||
|
enable_agc: 'False'
|
||||||
|
freq: '900000000.0'
|
||||||
|
maxoutbuf: '0'
|
||||||
|
minoutbuf: '0'
|
||||||
|
rx_bw: '2500000.0'
|
||||||
|
rx_gain: '40.0'
|
||||||
|
sample_rate: '4000000.0'
|
||||||
|
states:
|
||||||
|
bus_sink: false
|
||||||
|
bus_source: false
|
||||||
|
bus_structure: null
|
||||||
|
coordinate: [296, 212.0]
|
||||||
|
rotation: 0
|
||||||
|
state: enabled
|
||||||
|
- name: qtgui_freq_sink_x_0
|
||||||
|
id: qtgui_freq_sink_x
|
||||||
|
parameters:
|
||||||
|
affinity: ''
|
||||||
|
alias: ''
|
||||||
|
alpha1: '1.0'
|
||||||
|
alpha10: '1.0'
|
||||||
|
alpha2: '1.0'
|
||||||
|
alpha3: '1.0'
|
||||||
|
alpha4: '1.0'
|
||||||
|
alpha5: '1.0'
|
||||||
|
alpha6: '1.0'
|
||||||
|
alpha7: '1.0'
|
||||||
|
alpha8: '1.0'
|
||||||
|
alpha9: '1.0'
|
||||||
|
autoscale: 'False'
|
||||||
|
average: '1.0'
|
||||||
|
axislabels: 'True'
|
||||||
|
bw: 4e6
|
||||||
|
color1: '"blue"'
|
||||||
|
color10: '"dark blue"'
|
||||||
|
color2: '"red"'
|
||||||
|
color3: '"green"'
|
||||||
|
color4: '"black"'
|
||||||
|
color5: '"cyan"'
|
||||||
|
color6: '"magenta"'
|
||||||
|
color7: '"yellow"'
|
||||||
|
color8: '"dark red"'
|
||||||
|
color9: '"dark green"'
|
||||||
|
comment: ''
|
||||||
|
ctrlpanel: 'False'
|
||||||
|
fc: '0'
|
||||||
|
fftsize: '1024'
|
||||||
|
freqhalf: 'True'
|
||||||
|
grid: 'False'
|
||||||
|
gui_hint: ''
|
||||||
|
label: Relative Gain
|
||||||
|
label1: ''
|
||||||
|
label10: ''''''
|
||||||
|
label2: ''''''
|
||||||
|
label3: ''''''
|
||||||
|
label4: ''''''
|
||||||
|
label5: ''''''
|
||||||
|
label6: ''''''
|
||||||
|
label7: ''''''
|
||||||
|
label8: ''''''
|
||||||
|
label9: ''''''
|
||||||
|
legend: 'True'
|
||||||
|
maxoutbuf: '0'
|
||||||
|
minoutbuf: '0'
|
||||||
|
name: '""'
|
||||||
|
nconnections: '1'
|
||||||
|
norm_window: 'False'
|
||||||
|
showports: 'False'
|
||||||
|
tr_chan: '0'
|
||||||
|
tr_level: '0.0'
|
||||||
|
tr_mode: qtgui.TRIG_MODE_FREE
|
||||||
|
tr_tag: '""'
|
||||||
|
type: complex
|
||||||
|
units: dB
|
||||||
|
update_time: '0.10'
|
||||||
|
width1: '1'
|
||||||
|
width10: '1'
|
||||||
|
width2: '1'
|
||||||
|
width3: '1'
|
||||||
|
width4: '1'
|
||||||
|
width5: '1'
|
||||||
|
width6: '1'
|
||||||
|
width7: '1'
|
||||||
|
width8: '1'
|
||||||
|
width9: '1'
|
||||||
|
wintype: window.WIN_BLACKMAN_hARRIS
|
||||||
|
ymax: '10'
|
||||||
|
ymin: '-140'
|
||||||
|
states:
|
||||||
|
bus_sink: false
|
||||||
|
bus_source: false
|
||||||
|
bus_structure: null
|
||||||
|
coordinate: [656, 236.0]
|
||||||
|
rotation: 0
|
||||||
|
state: enabled
|
||||||
|
|
||||||
|
connections:
|
||||||
|
- [caribouLite_caribouLiteSource_0, '0', qtgui_freq_sink_x_0, '0']
|
||||||
|
|
||||||
|
metadata:
|
||||||
|
file_format: 1
|
||||||
|
grc_version: v3.11.0.0git-604-gd7f88722
|
|
@ -1,7 +1,7 @@
|
||||||
id: caribouLite_caribouLiteSource
|
id: caribouLite_caribouLiteSource
|
||||||
label: CaribouLite Source
|
label: CaribouLite Source
|
||||||
category: '[caribouLite]'
|
category: '[caribouLite]'
|
||||||
flags: throttle
|
flags: [python,cpp,throttle]
|
||||||
|
|
||||||
templates:
|
templates:
|
||||||
imports:
|
imports:
|
||||||
|
@ -9,13 +9,6 @@ templates:
|
||||||
make:
|
make:
|
||||||
caribouLite.caribouLiteSource(${channel}, ${enable_agc}, ${rx_gain}, ${rx_bw}, ${sample_rate}, ${freq})
|
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:
|
parameters:
|
||||||
- id: channel
|
- id: channel
|
||||||
label: S1G(0) or HiF(1)
|
label: S1G(0) or HiF(1)
|
||||||
|
@ -47,23 +40,21 @@ parameters:
|
||||||
dtype: float
|
dtype: float
|
||||||
default: 900000000.0
|
default: 900000000.0
|
||||||
|
|
||||||
|
cpp_templates:
|
||||||
# Make one 'inputs' list entry per input and one 'outputs' list entry per output.
|
includes: ['#include <gnuradio/caribouLite/caribouLiteSource.h>']
|
||||||
# Keys include:
|
declarations: 'caribouLite::caribouLiteSource::sptr ${id};'
|
||||||
# * label (an identifier for the GUI)
|
make: 'this->${id} = caribouLite::caribouLiteSource::make(${channel}, ${enable_agc}, ${rx_gain}, ${rx_bw}, ${sample_rate}, ${freq});'
|
||||||
# * domain (optional - stream or message. Default is stream)
|
packages: ['gnuradio-caribouLite']
|
||||||
# * dtype (e.g. int, float, complex, byte, short, xxx_vector, ...)
|
link: ['gnuradio::gnuradio-caribouLite']
|
||||||
# * vlen (optional - data stream vector length. Default is 1)
|
translations:
|
||||||
# * optional (optional - set to 1 for optional inputs. Default is 0)
|
'False': 'false'
|
||||||
inputs:
|
'True': 'true'
|
||||||
|
\[: '{'
|
||||||
|
\]: '}'
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
- label: samples
|
- label: samples
|
||||||
domain: stream
|
domain: stream
|
||||||
dtype: complex
|
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
|
file_format: 1
|
||||||
|
|
|
@ -40,40 +40,36 @@ 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)
|
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::sync_block("caribouLiteSource",
|
||||||
gr::io_signature::make(0, 0, 0),
|
gr::io_signature::make(0, 0, 0),
|
||||||
gr::io_signature::make(1 /* min outputs */, 1 /*max outputs */, sizeof(output_type)))
|
gr::io_signature::make(1 /* min outputs */, 1 /*max outputs */, sizeof(output_type)))
|
||||||
{
|
{
|
||||||
_rx_queue = NULL;
|
detectBoard();
|
||||||
|
|
||||||
_channel = (CaribouLiteRadio::RadioType)channel;
|
_channel = (CaribouLiteRadio::RadioType)channel;
|
||||||
_enable_agc = enable_agc;
|
_enable_agc = enable_agc;
|
||||||
_rx_gain = rx_gain;
|
_rx_gain = rx_gain;
|
||||||
_rx_bw = rx_bw;
|
_rx_bw = rx_bw;
|
||||||
_sample_rate = sample_rate;
|
_sample_rate = sample_rate;
|
||||||
_frequency = freq;
|
_frequency = freq;
|
||||||
detectBoard();
|
CaribouLite &cl = CaribouLite::GetInstance(false);
|
||||||
CaribouLite &cl = CaribouLite::GetInstance();
|
|
||||||
_cl = &cl;
|
_cl = &cl;
|
||||||
_radio = cl.GetRadioChannel(_channel);
|
_radio = cl.GetRadioChannel(_channel);
|
||||||
|
|
||||||
_mtu_size = _radio->GetNativeMtuSample();
|
_mtu_size = _radio->GetNativeMtuSample();
|
||||||
|
|
||||||
_rx_queue = new circular_buffer<gr_complex>(_mtu_size * NUM_NATIVE_MTUS_PER_QUEUE,
|
|
||||||
USE_ASYNC_OVERRIDE_WRITES,
|
|
||||||
USE_ASYNC_BLOCK_READS);
|
|
||||||
|
|
||||||
// setup parameters
|
// setup parameters
|
||||||
_radio->SetRxGain(rx_gain);
|
_radio->SetRxGain(rx_gain);
|
||||||
_radio->SetAgc(enable_agc);
|
_radio->SetAgc(enable_agc);
|
||||||
_radio->SetRxBandwidth(rx_bw);
|
_radio->SetRxBandwidth(rx_bw);
|
||||||
_radio->SetRxSampleRate(sample_rate);
|
_radio->SetRxSampleRate(sample_rate);
|
||||||
_radio->SetFrequency(freq);
|
_radio->SetFrequency(freq);
|
||||||
_radio->StartReceiving([this](CaribouLiteRadio* radio, const std::complex<float>* samples, CaribouLiteMeta* sync, size_t num_samples) {
|
|
||||||
receivedSamples(radio, samples, sync, num_samples);
|
//do the thing
|
||||||
});
|
_radio->StartReceiving();
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual destructor
|
// virtual destructor
|
||||||
|
@ -81,25 +77,15 @@ namespace gr {
|
||||||
caribouLiteSource_impl::~caribouLiteSource_impl()
|
caribouLiteSource_impl::~caribouLiteSource_impl()
|
||||||
{
|
{
|
||||||
_radio->StopReceiving();
|
_radio->StopReceiving();
|
||||||
if (_rx_queue) delete _rx_queue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receive samples callback
|
|
||||||
//-------------------------------------------------------------------------------------------------------------
|
|
||||||
void caribouLiteSource_impl::receivedSamples(CaribouLiteRadio* radio, const std::complex<float>* 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<const gr_complex*>(samples), num_samples);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------------
|
||||||
int caribouLiteSource_impl::work( int noutput_items,
|
int caribouLiteSource_impl::work(int noutput_items,
|
||||||
gr_vector_const_void_star &input_items,
|
gr_vector_const_void_star &input_items,
|
||||||
gr_vector_void_star &output_items)
|
gr_vector_void_star &output_items)
|
||||||
{
|
{
|
||||||
auto out = static_cast<output_type*>(output_items[0]);
|
auto out = static_cast<output_type*>(output_items[0]);
|
||||||
size_t num_read = _rx_queue->get(out, noutput_items);
|
return _radio->ReadSamples(out, static_cast<size_t>(noutput_items));
|
||||||
return noutput_items;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace caribouLite */
|
} /* namespace caribouLite */
|
||||||
|
|
|
@ -10,16 +10,17 @@
|
||||||
|
|
||||||
#include <gnuradio/caribouLite/caribouLiteSource.h>
|
#include <gnuradio/caribouLite/caribouLiteSource.h>
|
||||||
#include <CaribouLite.hpp>
|
#include <CaribouLite.hpp>
|
||||||
#include "circular_buffer.h"
|
|
||||||
|
|
||||||
namespace gr
|
namespace gr
|
||||||
{
|
{
|
||||||
namespace caribouLite
|
namespace caribouLite
|
||||||
{
|
{
|
||||||
|
void detectBoard();
|
||||||
|
|
||||||
class caribouLiteSource_impl : public caribouLiteSource
|
class caribouLiteSource_impl : public caribouLiteSource
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
CaribouLiteRadio::RadioType _channel;
|
CaribouLiteRadio::RadioType _channel; //RadioType, NOT frequency
|
||||||
bool _enable_agc;
|
bool _enable_agc;
|
||||||
float _rx_gain;
|
float _rx_gain;
|
||||||
float _rx_bw;
|
float _rx_bw;
|
||||||
|
@ -29,10 +30,6 @@ namespace gr
|
||||||
|
|
||||||
CaribouLite* _cl;
|
CaribouLite* _cl;
|
||||||
CaribouLiteRadio *_radio;
|
CaribouLiteRadio *_radio;
|
||||||
circular_buffer<gr_complex> *_rx_queue;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void receivedSamples(CaribouLiteRadio* radio, const std::complex<float>* samples, CaribouLiteMeta* sync, size_t num_samples);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
caribouLiteSource_impl(int channel, bool enable_agc, float rx_gain, float rx_bw, float sample_rate, float freq);
|
caribouLiteSource_impl(int channel, bool enable_agc, float rx_gain, float rx_bw, float sample_rate, float freq);
|
||||||
|
|
|
@ -1,165 +0,0 @@
|
||||||
#ifndef __CIRC_BUFFER_H__
|
|
||||||
#define __CIRC_BUFFER_H__
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <thread>
|
|
||||||
#include <mutex>
|
|
||||||
#include <condition_variable>
|
|
||||||
#include <chrono>
|
|
||||||
#include <atomic>
|
|
||||||
|
|
||||||
#define IS_POWER_OF_2(x) (!((x) == 0) && !((x) & ((x) - 1)))
|
|
||||||
#define MIN(x,y) ((x)>(y)?(y):(x))
|
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
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<std::mutex> lock(mutex_);
|
|
||||||
delete []buf_;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t put(const T *data, size_t length)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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
|
|
Ładowanie…
Reference in New Issue