summaryrefslogtreecommitdiff
path: root/gr-iio/lib/fmcomms2_source_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gr-iio/lib/fmcomms2_source_impl.cc')
-rw-r--r--gr-iio/lib/fmcomms2_source_impl.cc207
1 files changed, 177 insertions, 30 deletions
diff --git a/gr-iio/lib/fmcomms2_source_impl.cc b/gr-iio/lib/fmcomms2_source_impl.cc
index e102e99247..e6651e49bc 100644
--- a/gr-iio/lib/fmcomms2_source_impl.cc
+++ b/gr-iio/lib/fmcomms2_source_impl.cc
@@ -19,6 +19,8 @@
#include <thread>
#include <vector>
+#include <volk/volk.h>
+
#define MIN_RATE 520333
#define DECINT_RATIO 8
#define OVERFLOW_CHECK_PERIOD_MS 1000
@@ -26,18 +28,20 @@
namespace gr {
namespace iio {
-fmcomms2_source::sptr fmcomms2_source::make(const std::string& uri,
- const std::vector<bool>& ch_en,
- unsigned long buffer_size)
+template <typename T>
+typename fmcomms2_source<T>::sptr fmcomms2_source<T>::make(const std::string& uri,
+ const std::vector<bool>& ch_en,
+ unsigned long buffer_size)
{
- return gnuradio::make_block_sptr<fmcomms2_source_impl>(
+ return gnuradio::make_block_sptr<fmcomms2_source_impl<T>>(
device_source_impl::get_context(uri), ch_en, buffer_size);
}
-std::vector<std::string> fmcomms2_source_impl::get_channels_vector(bool ch1_en,
- bool ch2_en,
- bool ch3_en,
- bool ch4_en)
+template <typename T>
+std::vector<std::string> fmcomms2_source_impl<T>::get_channels_vector(bool ch1_en,
+ bool ch2_en,
+ bool ch3_en,
+ bool ch4_en)
{
std::vector<std::string> channels;
if (ch1_en)
@@ -51,8 +55,9 @@ std::vector<std::string> fmcomms2_source_impl::get_channels_vector(bool ch1_en,
return channels;
}
+template <typename T>
std::vector<std::string>
-fmcomms2_source_impl::get_channels_vector(const std::vector<bool>& ch_en)
+fmcomms2_source_impl<T>::get_channels_vector(const std::vector<bool>& ch_en)
{
std::vector<std::string> channels;
int idx = 0;
@@ -66,13 +71,32 @@ fmcomms2_source_impl::get_channels_vector(const std::vector<bool>& ch_en)
return channels;
}
+template <>
+fmcomms2_source_impl<int16_t>::fmcomms2_source_impl(iio_context* ctx,
+ const std::vector<bool>& ch_en,
+ unsigned long buffer_size)
+ : gr::sync_block("fmcomms2_source",
+ gr::io_signature::make(0, 0, 0),
+ gr::io_signature::make(1, -1, sizeof(int16_t))),
+ device_source_impl(ctx,
+ true,
+ "cf-ad9361-lpc",
+ get_channels_vector(ch_en),
+ "ad9361-phy",
+ std::vector<std::string>(),
+ buffer_size,
+ 0)
+{
+ overflow_thd = std::thread(&fmcomms2_source_impl<int16_t>::check_overflow, this);
+}
-fmcomms2_source_impl::fmcomms2_source_impl(iio_context* ctx,
- const std::vector<bool>& ch_en,
- unsigned long buffer_size)
+template <typename T>
+fmcomms2_source_impl<T>::fmcomms2_source_impl(iio_context* ctx,
+ const std::vector<bool>& ch_en,
+ unsigned long buffer_size)
: gr::sync_block("fmcomms2_source",
gr::io_signature::make(0, 0, 0),
- gr::io_signature::make(1, -1, sizeof(short))),
+ gr::io_signature::make(1, -1, sizeof(T))),
device_source_impl(ctx,
true,
"cf-ad9361-lpc",
@@ -82,12 +106,25 @@ fmcomms2_source_impl::fmcomms2_source_impl(iio_context* ctx,
buffer_size,
0)
{
- overflow_thd = std::thread(&fmcomms2_source_impl::check_overflow, this);
+ overflow_thd = std::thread(&fmcomms2_source_impl<T>::check_overflow, this);
+
+ // Device Buffers are always presented as short from device_sink
+ d_device_bufs.resize(get_channels_vector(ch_en).size());
+ for (size_t i = 0; i < d_device_bufs.size(); i++) {
+ d_device_bufs[i].resize(s_initial_device_buf_size);
+ }
+ d_float_ivec.resize(s_initial_device_buf_size);
+ d_float_rvec.resize(s_initial_device_buf_size);
}
-fmcomms2_source_impl::~fmcomms2_source_impl() { overflow_thd.join(); }
+template <typename T>
+fmcomms2_source_impl<T>::~fmcomms2_source_impl()
+{
+ overflow_thd.join();
+}
-void fmcomms2_source_impl::check_overflow(void)
+template <typename T>
+void fmcomms2_source_impl<T>::check_overflow(void)
{
uint32_t status;
int ret;
@@ -126,7 +163,103 @@ void fmcomms2_source_impl::check_overflow(void)
}
}
-void fmcomms2_source_impl::update_dependent_params()
+
+template <>
+int fmcomms2_source_impl<std::int16_t>::work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ if (2 * output_items.size() > d_device_item_ptrs.size()) {
+ d_device_item_ptrs.resize(2 * output_items.size());
+ }
+
+ for (size_t i = 0; i < 2 * output_items.size(); i += 2) {
+ if (noutput_items > (int)d_device_bufs[i].size()) {
+ d_device_bufs[i].resize(noutput_items);
+ d_device_bufs[i + 1].resize(noutput_items);
+ }
+ d_device_item_ptrs[i] = static_cast<void*>(d_device_bufs[i].data());
+ d_device_item_ptrs[i + 1] = static_cast<void*>(d_device_bufs[i + 1].data());
+ }
+
+
+ // Since device_source returns shorts, we can just pass off the work
+ int ret = device_source_impl::work(noutput_items, input_items, d_device_item_ptrs);
+ if (ret <= 0) {
+ return ret;
+ }
+
+ // Do the conversion from shorts to interleaved shorts
+ for (size_t i = 0; i < output_items.size(); i += 2) {
+ auto out = static_cast<short*>(output_items[i]);
+
+ for (int j = 0; j < noutput_items; j++) {
+ out[2 * j] = d_device_bufs[i][j];
+ out[2 * j + 1] = d_device_bufs[i + 1][j];
+ }
+ }
+
+ return ret;
+}
+
+
+template <>
+int fmcomms2_source_impl<gr_complex>::work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ if (2 * output_items.size() > d_device_item_ptrs.size()) {
+ d_device_item_ptrs.resize(2 * output_items.size());
+ }
+ if (noutput_items > (int)d_float_rvec.size()) {
+ d_float_rvec.resize(noutput_items);
+ d_float_ivec.resize(noutput_items);
+ }
+ for (size_t i = 0; i < 2 * output_items.size(); i += 2) {
+ if (noutput_items > (int)d_device_bufs[i].size()) {
+ d_device_bufs[i].resize(noutput_items);
+ d_device_bufs[i + 1].resize(noutput_items);
+ }
+ d_device_item_ptrs[i] = static_cast<void*>(d_device_bufs[i].data());
+ d_device_item_ptrs[i + 1] = static_cast<void*>(d_device_bufs[i + 1].data());
+ }
+
+ int ret = device_source_impl::work(noutput_items, input_items, d_device_item_ptrs);
+ if (ret <= 0) {
+ return ret;
+ }
+
+ // Do the conversion from shorts to gr_complex
+ for (size_t i = 0; i < output_items.size(); i++) {
+ auto out = static_cast<gr_complex*>(output_items[i]);
+
+ // for (int n = 0; n < noutput_items; n++) {
+ // out[n] = gr_complex(float(d_device_bufs[i][n]) / 2048.0,
+ // float(d_device_bufs[i+1][n]) / 2048.0);
+ // }
+
+ volk_16i_s32f_convert_32f(
+ d_float_rvec.data(), d_device_bufs[i].data(), 2048.0, noutput_items);
+ volk_16i_s32f_convert_32f(
+ d_float_ivec.data(), d_device_bufs[i + 1].data(), 2048.0, noutput_items);
+
+ volk_32f_x2_interleave_32fc(
+ out, d_float_rvec.data(), d_float_ivec.data(), noutput_items);
+ }
+
+ return ret;
+}
+
+template <typename T>
+int fmcomms2_source_impl<T>::work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ return device_source_impl::work(noutput_items, input_items, output_items);
+}
+
+template <typename T>
+void fmcomms2_source_impl<T>::update_dependent_params()
{
std::vector<std::string> params;
// Set rate configuration
@@ -162,19 +295,22 @@ void fmcomms2_source_impl::update_dependent_params()
}
}
-void fmcomms2_source_impl::set_len_tag_key(const std::string& len_tag_key)
+template <typename T>
+void fmcomms2_source_impl<T>::set_len_tag_key(const std::string& len_tag_key)
{
device_source_impl::set_len_tag_key(len_tag_key);
}
-void fmcomms2_source_impl::set_frequency(unsigned long long frequency)
+template <typename T>
+void fmcomms2_source_impl<T>::set_frequency(unsigned long long frequency)
{
std::vector<std::string> params;
params.push_back("out_altvoltage0_RX_LO_frequency=" + std::to_string(frequency));
device_source_impl::set_params(params);
}
-void fmcomms2_source_impl::set_samplerate(unsigned long samplerate)
+template <typename T>
+void fmcomms2_source_impl<T>::set_samplerate(unsigned long samplerate)
{
std::vector<std::string> params;
if (samplerate < MIN_RATE) {
@@ -195,7 +331,8 @@ void fmcomms2_source_impl::set_samplerate(unsigned long samplerate)
update_dependent_params();
}
-void fmcomms2_source_impl::set_gain_mode(size_t chan, const std::string& mode)
+template <typename T>
+void fmcomms2_source_impl<T>::set_gain_mode(size_t chan, const std::string& mode)
{
bool is_fmcomms4 = !iio_device_find_channel(phy, "voltage1", false);
if ((!is_fmcomms4 && chan > 0) || chan > 1) {
@@ -210,8 +347,8 @@ void fmcomms2_source_impl::set_gain_mode(size_t chan, const std::string& mode)
d_gain_mode[chan] = mode;
}
-
-void fmcomms2_source_impl::set_gain(size_t chan, double gain_value)
+template <typename T>
+void fmcomms2_source_impl<T>::set_gain(size_t chan, double gain_value)
{
bool is_fmcomms4 = !iio_device_find_channel(phy, "voltage1", false);
if ((!is_fmcomms4 && chan > 0) || chan > 1) {
@@ -231,21 +368,26 @@ void fmcomms2_source_impl::set_gain(size_t chan, double gain_value)
d_gain_value[chan] = gain_value;
}
-void fmcomms2_source_impl::set_quadrature(bool quadrature)
+template <typename T>
+void fmcomms2_source_impl<T>::set_quadrature(bool quadrature)
{
std::vector<std::string> params;
params.push_back("in_voltage_quadrature_tracking_en=" + std::to_string(quadrature));
device_source_impl::set_params(params);
d_quadrature = quadrature;
}
-void fmcomms2_source_impl::set_rfdc(bool rfdc)
+
+template <typename T>
+void fmcomms2_source_impl<T>::set_rfdc(bool rfdc)
{
std::vector<std::string> params;
params.push_back("in_voltage_rf_dc_offset_tracking_en=" + std::to_string(rfdc));
device_source_impl::set_params(params);
d_rfdc = rfdc;
}
-void fmcomms2_source_impl::set_bbdc(bool bbdc)
+
+template <typename T>
+void fmcomms2_source_impl<T>::set_bbdc(bool bbdc)
{
std::vector<std::string> params;
params.push_back("in_voltage_bb_dc_offset_tracking_en=" + std::to_string(bbdc));
@@ -253,10 +395,11 @@ void fmcomms2_source_impl::set_bbdc(bool bbdc)
d_bbdc = bbdc;
}
-void fmcomms2_source_impl::set_filter_params(const std::string& filter_source,
- const std::string& filter_filename,
- float fpass,
- float fstop)
+template <typename T>
+void fmcomms2_source_impl<T>::set_filter_params(const std::string& filter_source,
+ const std::string& filter_filename,
+ float fpass,
+ float fstop)
{
d_filter_source = filter_source;
d_filter_filename = filter_filename;
@@ -266,5 +409,9 @@ void fmcomms2_source_impl::set_filter_params(const std::string& filter_source,
update_dependent_params();
}
+template class fmcomms2_source<int16_t>;
+template class fmcomms2_source<std::complex<int16_t>>;
+template class fmcomms2_source<gr_complex>;
+
} /* namespace iio */
} /* namespace gr */