mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-11-13 21:57:14 +00:00
Merge with next and adding full suport for custom AD936x sample sizes and dual frequency modes with external mixer board
This commit is contained in:
@@ -109,16 +109,19 @@ Ad936xCustomSignalSource::Ad936xCustomSignalSource(const ConfigurationInterface*
|
||||
else if (ssize_ == 8)
|
||||
{
|
||||
gr_interleaved_char_to_complex_.push_back(gr::blocks::interleaved_char_to_complex::make());
|
||||
unpack_short_byte.push_back(make_unpack_short_byte_samples());
|
||||
}
|
||||
else if (ssize_ == 4)
|
||||
{
|
||||
gr_interleaved_short_to_complex_.push_back(gr::blocks::interleaved_short_to_complex::make(false, false));
|
||||
unpack_byte_fourbits.push_back(make_unpack_byte_4bit_samples());
|
||||
unpack_short_byte.push_back(make_unpack_short_byte_samples());
|
||||
}
|
||||
else if (ssize_ == 2)
|
||||
{
|
||||
gr_interleaved_short_to_complex_.push_back(gr::blocks::interleaved_short_to_complex::make(false, false));
|
||||
unpack_byte_twobits.push_back(make_unpack_byte_2bit_cpx_samples());
|
||||
unpack_short_byte.push_back(make_unpack_short_byte_samples());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,7 +168,8 @@ void Ad936xCustomSignalSource::connect(gr::top_block_sptr top_block)
|
||||
}
|
||||
else if (ssize_ == 8)
|
||||
{
|
||||
top_block->connect(ad936x_iio_source, n, gr_interleaved_char_to_complex_.at(n), 0);
|
||||
top_block->connect(ad936x_iio_source, n, unpack_short_byte.at(n), 0);
|
||||
top_block->connect(unpack_short_byte.at(n), 0, gr_interleaved_char_to_complex_.at(n), 0);
|
||||
DLOG(INFO) << "connected ad936x_iio_source source to gr_interleaved_char_to_complex_ for channel " << n;
|
||||
if (dump_)
|
||||
{
|
||||
@@ -175,7 +179,8 @@ void Ad936xCustomSignalSource::connect(gr::top_block_sptr top_block)
|
||||
}
|
||||
else if (ssize_ == 4)
|
||||
{
|
||||
top_block->connect(ad936x_iio_source, n, unpack_byte_fourbits.at(n), 0);
|
||||
top_block->connect(ad936x_iio_source, n, unpack_short_byte.at(n), 0);
|
||||
top_block->connect(unpack_short_byte.at(n), 0, unpack_byte_fourbits.at(n), 0);
|
||||
top_block->connect(unpack_byte_fourbits.at(n), 0, gr_interleaved_short_to_complex_.at(n), 0);
|
||||
DLOG(INFO) << "connected ad936x_iio_source source to unpack_byte_fourbits for channel " << n;
|
||||
if (dump_)
|
||||
@@ -186,7 +191,8 @@ void Ad936xCustomSignalSource::connect(gr::top_block_sptr top_block)
|
||||
}
|
||||
else if (ssize_ == 2)
|
||||
{
|
||||
top_block->connect(ad936x_iio_source, n, unpack_byte_twobits.at(n), 0);
|
||||
top_block->connect(ad936x_iio_source, n, unpack_short_byte.at(n), 0);
|
||||
top_block->connect(unpack_short_byte.at(n), 0, unpack_byte_twobits.at(n), 0);
|
||||
top_block->connect(unpack_byte_twobits.at(n), 0, gr_interleaved_short_to_complex_.at(n), 0);
|
||||
DLOG(INFO) << "connected ad936x_iio_source source to unpack_byte_fourbits for channel " << n;
|
||||
if (dump_)
|
||||
@@ -216,53 +222,56 @@ void Ad936xCustomSignalSource::disconnect(gr::top_block_sptr top_block)
|
||||
if (ssize_ == 16)
|
||||
{
|
||||
top_block->disconnect(ad936x_iio_source, n, gr_interleaved_short_to_complex_.at(n), 0);
|
||||
DLOG(INFO) << "connected ad936x_iio_source source to gr_interleaved_short_to_complex for channel " << n;
|
||||
DLOG(INFO) << "disconnect ad936x_iio_source source to gr_interleaved_short_to_complex for channel " << n;
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
|
||||
DLOG(INFO) << "connected source to file sink";
|
||||
DLOG(INFO) << "disconnect source to file sink";
|
||||
}
|
||||
}
|
||||
else if (ssize_ == 8)
|
||||
{
|
||||
top_block->disconnect(ad936x_iio_source, n, gr_interleaved_char_to_complex_.at(n), 0);
|
||||
DLOG(INFO) << "connected ad936x_iio_source source to gr_interleaved_char_to_complex_ for channel " << n;
|
||||
top_block->connect(ad936x_iio_source, n, unpack_short_byte.at(n), 0);
|
||||
top_block->connect(unpack_short_byte.at(n), 0, unpack_byte_fourbits.at(n), 0);
|
||||
DLOG(INFO) << "disconnect ad936x_iio_source source to gr_interleaved_char_to_complex_ for channel " << n;
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(gr_interleaved_char_to_complex_.at(n), 0, sink_.at(n), 0);
|
||||
DLOG(INFO) << "connected source to file sink";
|
||||
DLOG(INFO) << "disconnect source to file sink";
|
||||
}
|
||||
}
|
||||
else if (ssize_ == 4)
|
||||
{
|
||||
top_block->disconnect(ad936x_iio_source, n, unpack_byte_fourbits.at(n), 0);
|
||||
top_block->disconnect(ad936x_iio_source, n, unpack_short_byte.at(n), 0);
|
||||
top_block->disconnect(unpack_short_byte.at(n), 0, unpack_byte_fourbits.at(n), 0);
|
||||
top_block->disconnect(unpack_byte_fourbits.at(n), 0, gr_interleaved_short_to_complex_.at(n), 0);
|
||||
DLOG(INFO) << "connected ad936x_iio_source source to unpack_byte_fourbits for channel " << n;
|
||||
DLOG(INFO) << "disconnect ad936x_iio_source source to unpack_byte_fourbits for channel " << n;
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
|
||||
DLOG(INFO) << "connected source to file sink";
|
||||
top_block->disconnect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
|
||||
DLOG(INFO) << "disconnect source to file sink";
|
||||
}
|
||||
}
|
||||
else if (ssize_ == 2)
|
||||
{
|
||||
top_block->disconnect(ad936x_iio_source, n, unpack_byte_twobits.at(n), 0);
|
||||
top_block->disconnect(ad936x_iio_source, n, unpack_short_byte.at(n), 0);
|
||||
top_block->disconnect(unpack_short_byte.at(n), 0, unpack_byte_twobits.at(n), 0);
|
||||
top_block->disconnect(unpack_byte_twobits.at(n), 0, gr_interleaved_short_to_complex_.at(n), 0);
|
||||
DLOG(INFO) << "connected ad936x_iio_source source to unpack_byte_fourbits for channel " << n;
|
||||
DLOG(INFO) << "disconnect ad936x_iio_source source to unpack_byte_fourbits for channel " << n;
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
|
||||
DLOG(INFO) << "connected source to file sink";
|
||||
DLOG(INFO) << "disconnect source to file sink";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
top_block->disconnect(ad936x_iio_source, n, gr_interleaved_short_to_complex_.at(n), 0);
|
||||
DLOG(INFO) << "connected ad936x_iio_source source to gr_interleaved_short_to_complex for channel " << n;
|
||||
DLOG(INFO) << "disconnect ad936x_iio_source source to gr_interleaved_short_to_complex for channel " << n;
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
|
||||
DLOG(INFO) << "connected source to file sink";
|
||||
DLOG(INFO) << "disconnect source to file sink";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "signal_source_base.h"
|
||||
#include "unpack_byte_2bit_cpx_samples.h"
|
||||
#include "unpack_byte_4bit_samples.h"
|
||||
#include "unpack_short_byte_samples.h"
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gnuradio/blocks/interleaved_char_to_complex.h>
|
||||
#include <gnuradio/blocks/interleaved_short_to_complex.h>
|
||||
@@ -74,6 +75,7 @@ private:
|
||||
|
||||
std::vector<gr::blocks::interleaved_short_to_complex::sptr> gr_interleaved_short_to_complex_;
|
||||
std::vector<gr::blocks::interleaved_char_to_complex::sptr> gr_interleaved_char_to_complex_;
|
||||
std::vector<unpack_short_byte_samples_sptr> unpack_short_byte;
|
||||
std::vector<unpack_byte_4bit_samples_sptr> unpack_byte_fourbits;
|
||||
std::vector<unpack_byte_2bit_cpx_samples_sptr> unpack_byte_twobits;
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES
|
||||
unpack_byte_2bit_cpx_samples.cc
|
||||
unpack_byte_4bit_samples.cc
|
||||
unpack_intspir_1bit_samples.cc
|
||||
unpack_short_byte_samples.cc
|
||||
rtl_tcp_signal_source_c.cc
|
||||
unpack_2bit_samples.cc
|
||||
unpack_spir_gss6450_samples.cc
|
||||
@@ -44,6 +45,7 @@ set(SIGNAL_SOURCE_GR_BLOCKS_HEADERS
|
||||
unpack_byte_2bit_cpx_samples.h
|
||||
unpack_byte_4bit_samples.h
|
||||
unpack_intspir_1bit_samples.h
|
||||
unpack_short_byte_samples.h
|
||||
rtl_tcp_signal_source_c.h
|
||||
unpack_2bit_samples.h
|
||||
unpack_spir_gss6450_samples.h
|
||||
|
||||
@@ -79,6 +79,21 @@ ad936x_iio_source_sptr ad936x_iio_make_source_sptr(
|
||||
spattern_));
|
||||
}
|
||||
|
||||
void ad936x_iio_source::ad9361_channel_demux_and_record(ad936x_iio_samples *samples_in, int nchannels, std::vector<std::fstream> *files_out)
|
||||
{
|
||||
int32_t current_byte = 0;
|
||||
int16_t ch = 0;
|
||||
// std::cout << "nbytes: " << samples_in->n_bytes << " nsamples: " << samples_in->n_samples << " nch: " << nchannels << "\n";
|
||||
while (current_byte < samples_in->n_bytes)
|
||||
{
|
||||
for (ch = 0; ch < nchannels; ch++)
|
||||
{
|
||||
//std::cout << current_byte << " of " << samples_in->n_bytes << " test: " << (int)samples_in->buffer[current_byte] << "\n";
|
||||
(*files_out).at(ch).write(&samples_in->buffer[current_byte], 4); //two bytes I + two bytes Q per channel
|
||||
current_byte += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ad936x_iio_source::ad936x_iio_source(
|
||||
std::string pluto_uri_,
|
||||
@@ -222,9 +237,22 @@ ad936x_iio_source::ad936x_iio_source(
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//set_min_noutput_items(IIO_DEFAULTAD936XAPIFIFOSIZE_SAMPLES * 2);
|
||||
set_min_output_buffer(IIO_DEFAULTAD936XAPIFIFOSIZE_SAMPLES * 2);
|
||||
set_min_noutput_items(IIO_DEFAULTAD936XAPIFIFOSIZE_SAMPLES * 2); // multiplexed I,Q, so, two samples per complex sample
|
||||
set_min_output_buffer(IIO_DEFAULTAD936XAPIFIFOSIZE_SAMPLES * sizeof(int16_t) * 2);
|
||||
//std::cout << "max_output_buffer " << min_output_buffer(0) << " min_noutput_items: " << min_noutput_items() << "\n";
|
||||
|
||||
// for (int n = 0; n < ad936x_custom->n_channels; n++)
|
||||
// {
|
||||
// std::string cap_file_root_name = "./debug_cap_ch";
|
||||
// samplesfile.push_back(std::fstream(cap_file_root_name + std::to_string(n) + ".dat", std::ios::out | std::ios::binary));
|
||||
// //samplesfile.back().exceptions(std::ios_base::badbit | std::ios_base::failbit); //this will enable exceptions for debug
|
||||
//
|
||||
// if (samplesfile.back().is_open() == false)
|
||||
// {
|
||||
// std::cout << "ERROR: Could not open " << cap_file_root_name + "_ch" + std::to_string(n) + ".dat"
|
||||
// << " for record samples!\n";
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
ad936x_iio_source::~ad936x_iio_source()
|
||||
@@ -246,6 +274,7 @@ bool ad936x_iio_source::start()
|
||||
|
||||
bool ad936x_iio_source::stop()
|
||||
{
|
||||
std::cout << "stopping ad936x_iio_source...\n";
|
||||
ad936x_custom->stop_record();
|
||||
return true;
|
||||
}
|
||||
@@ -261,16 +290,46 @@ int ad936x_iio_source::general_work(int noutput_items,
|
||||
current_samples = current_buffer.get();
|
||||
|
||||
//I and Q samples are interleaved in buffer: IQIQIQ...
|
||||
|
||||
for (size_t n = 0; n < ad936x_custom->n_channels; n++)
|
||||
int32_t n_interleaved_iq_samples_per_channel = current_samples->n_bytes / (ad936x_custom->n_channels * 2);
|
||||
if (noutput_items < n_interleaved_iq_samples_per_channel)
|
||||
{
|
||||
if (output_items.size() > n) // check if the output channel is connected
|
||||
{
|
||||
memcpy(reinterpret_cast<void *>(output_items[n]), reinterpret_cast<void *>(current_samples->buffer[n]), current_samples->n_bytes[n]);
|
||||
produce(n, current_samples->n_samples[n]);
|
||||
}
|
||||
std::cout << "ad936x_iio_source output buffer overflow! noutput_items: " << noutput_items << " vs. " << n_interleaved_iq_samples_per_channel << "\n";
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//ad9361_channel_demux_and_record(current_samples, ad936x_custom->n_channels, &samplesfile);
|
||||
|
||||
ad936x_custom->push_sample_buffer(current_buffer);
|
||||
return this->WORK_CALLED_PRODUCE;
|
||||
uint32_t current_byte = 0;
|
||||
uint32_t current_byte_in_gr = 0;
|
||||
int16_t ch = 0;
|
||||
//std::cout << "nbytes: " << samples_in->n_bytes << " nsamples: " << samples_in->n_samples << " nch: " << nchannels << "\n";
|
||||
if (ad936x_custom->n_channels == 1)
|
||||
{
|
||||
memcpy(&((char *)output_items[0])[0], ¤t_samples->buffer[current_byte], current_samples->n_bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (current_byte < current_samples->n_bytes)
|
||||
|
||||
{
|
||||
for (ch = 0; ch < ad936x_custom->n_channels; ch++)
|
||||
{
|
||||
memcpy(&((char *)output_items[ch])[current_byte_in_gr], ¤t_samples->buffer[current_byte], 4); // two bytes I + two bytes Q per channel: 4 bytes
|
||||
current_byte += 4;
|
||||
}
|
||||
current_byte_in_gr += 4;
|
||||
}
|
||||
}
|
||||
ad936x_custom->push_sample_buffer(current_buffer);
|
||||
return n_interleaved_iq_samples_per_channel; // always int16_t samples interleaved (I,Q,I,Q)
|
||||
|
||||
// for (size_t n = 0; n < ad936x_custom->n_channels; n++)
|
||||
// {
|
||||
// produce(n, current_samples->n_samples[n]);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// return this->WORK_CALLED_PRODUCE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
@@ -131,12 +132,16 @@ private:
|
||||
int bshift_,
|
||||
bool spattern_);
|
||||
|
||||
|
||||
void ad9361_channel_demux_to_buffer(ad936x_iio_samples *samples_in, int nchannels, gr_vector_void_star &output_items);
|
||||
void ad9361_channel_demux_and_record(ad936x_iio_samples *samples_in, int nchannels, std::vector<std::fstream> *files_out);
|
||||
|
||||
std::thread pps_rx_thread;
|
||||
|
||||
|
||||
std::unique_ptr<ad936x_iio_custom> ad936x_custom;
|
||||
std::shared_ptr<pps_tcp_rx> pps_rx;
|
||||
std::shared_ptr<Concurrent_Queue<PpsSamplestamp>> ppsqueue;
|
||||
|
||||
std::vector<std::fstream> samplesfile;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*!
|
||||
* \file unpack_short_byte_samples.cc
|
||||
*
|
||||
* \brief Unpacks shorts samples to byte samples (1 short = 2 byte samples).
|
||||
* Packing Order
|
||||
* Packing order in Nibble I0 I1
|
||||
* \author Javier Arribas jarribas (at) cttc.es
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2022 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "unpack_short_byte_samples.h"
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
unpack_short_byte_samples_sptr make_unpack_short_byte_samples()
|
||||
{
|
||||
return unpack_short_byte_samples_sptr(new unpack_short_byte_samples());
|
||||
}
|
||||
|
||||
|
||||
unpack_short_byte_samples::unpack_short_byte_samples() : sync_interpolator("unpack_short_byte_samples",
|
||||
gr::io_signature::make(1, 1, sizeof(int16_t)),
|
||||
gr::io_signature::make(1, 1, sizeof(int8_t)),
|
||||
2)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void unpack_short_byte_samples::forecast(int noutput_items,
|
||||
gr_vector_int &ninput_items_required)
|
||||
{
|
||||
if (noutput_items != 0)
|
||||
{
|
||||
ninput_items_required[0] = static_cast<int32_t>(noutput_items) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
int unpack_short_byte_samples::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
// const auto *in = reinterpret_cast<const int16_t *>(input_items[0]);
|
||||
// auto *out = reinterpret_cast<int8_t *>(output_items[0]);
|
||||
|
||||
memcpy(reinterpret_cast<int8_t *>(output_items[0]), reinterpret_cast<const int8_t *>(input_items[0]), noutput_items);
|
||||
|
||||
return noutput_items;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*!
|
||||
* \file unpack_short_byte_samples.cc
|
||||
*
|
||||
* \brief Unpacks shorts samples to byte samples (1 short = 2 byte samples).
|
||||
* Packing Order
|
||||
* Packing order in Nibble I0 I1
|
||||
* \author Javier Arribas jarribas (at) cttc.es
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2022 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_UNPACK_SHORT_BYTE_SAMPLES_H
|
||||
#define GNSS_SDR_UNPACK_SHORT_BYTE_SAMPLES_H
|
||||
|
||||
#include "gnss_block_interface.h"
|
||||
#include <gnuradio/sync_interpolator.h>
|
||||
|
||||
/** \addtogroup Signal_Source
|
||||
* \{ */
|
||||
/** \addtogroup Signal_Source_gnuradio_blocks
|
||||
* \{ */
|
||||
|
||||
|
||||
class unpack_short_byte_samples;
|
||||
|
||||
using unpack_short_byte_samples_sptr = gnss_shared_ptr<unpack_short_byte_samples>;
|
||||
|
||||
unpack_short_byte_samples_sptr make_unpack_short_byte_samples();
|
||||
|
||||
/*!
|
||||
* \brief This class implements conversion between short packet samples to byte samples
|
||||
* 1 short = 2 byte samples
|
||||
*/
|
||||
class unpack_short_byte_samples : public gr::sync_interpolator
|
||||
{
|
||||
public:
|
||||
unpack_short_byte_samples();
|
||||
void forecast(int noutput_items, gr_vector_int &ninput_items_required);
|
||||
~unpack_short_byte_samples() = default;
|
||||
int work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items);
|
||||
|
||||
private:
|
||||
friend unpack_short_byte_samples_sptr make_unpack_short_byte_samples_sptr();
|
||||
};
|
||||
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
||||
#endif // GNSS_SDR_UNPACK_SHORT_BYTE_SAMPLES_H
|
||||
@@ -92,14 +92,6 @@ if(GNURADIO_USES_STD_POINTERS)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(GNURADIO_USES_SPDLOG)
|
||||
target_link_libraries(signal_source_libs
|
||||
PUBLIC
|
||||
fmt::fmt
|
||||
spdlog::spdlog
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_FMCOMMS2 OR ENABLE_AD9361 OR ENABLE_PLUTOSDR)
|
||||
target_link_libraries(signal_source_libs
|
||||
PUBLIC
|
||||
|
||||
@@ -247,7 +247,8 @@ bool ad936x_iio_custom::config_ad9361_dds(uint64_t freq_rf_tx_hz_,
|
||||
double tx_attenuation_db_,
|
||||
int64_t freq_dds_tx_hz_,
|
||||
double scale_dds_,
|
||||
double phase_dds_deg_)
|
||||
double phase_dds_deg_,
|
||||
int channel)
|
||||
{
|
||||
// TX stream config
|
||||
std::cout << "Start of AD9361 TX Oscillator DDS configuration\n";
|
||||
@@ -260,52 +261,60 @@ bool ad936x_iio_custom::config_ad9361_dds(uint64_t freq_rf_tx_hz_,
|
||||
|
||||
params_phy.push_back("out_altvoltage1_TX_LO_frequency=" +
|
||||
std::to_string(freq_rf_tx_hz_));
|
||||
|
||||
params_phy.push_back("out_voltage0_hardwaregain=" +
|
||||
std::to_string(-tx_attenuation_db_));
|
||||
|
||||
//disable the other TX
|
||||
params_phy.push_back("out_voltage1_hardwaregain=" +
|
||||
std::to_string(-tx_attenuation_db_));
|
||||
|
||||
|
||||
double disabled_tx_attenuation = 89.75;
|
||||
if (channel == 1)
|
||||
{
|
||||
params_phy.push_back("out_voltage0_hardwaregain=" +
|
||||
std::to_string(-tx_attenuation_db_));
|
||||
//disable the other TX
|
||||
params_phy.push_back("out_voltage1_hardwaregain=" +
|
||||
std::to_string(-disabled_tx_attenuation));
|
||||
}
|
||||
else
|
||||
{
|
||||
params_phy.push_back("out_voltage1_hardwaregain=" +
|
||||
std::to_string(-tx_attenuation_db_));
|
||||
//disable the other TX
|
||||
params_phy.push_back("out_voltage0_hardwaregain=" +
|
||||
std::to_string(-disabled_tx_attenuation));
|
||||
}
|
||||
configure_params(phy, params_phy);
|
||||
|
||||
std::vector<std::string> params_dds;
|
||||
|
||||
//DDS TX CH1 I (tone #1)
|
||||
params_dds.push_back("out_altvoltage0_TX1_I_F1_frequency=" +
|
||||
std::to_string(freq_dds_tx_hz_));
|
||||
params_dds.push_back("out_altvoltage0_TX1_I_F1_phase=" +
|
||||
std::to_string(phase_dds_deg_ * 1000.0));
|
||||
params_dds.push_back("out_altvoltage0_TX1_I_F1_scale=" +
|
||||
std::to_string(scale_dds_));
|
||||
params_dds.push_back("out_altvoltage0_TX1_I_F1_raw=1");
|
||||
//DDS TX CH1 Q (tone #1)
|
||||
params_dds.push_back("out_altvoltage2_TX1_Q_F1_frequency=" +
|
||||
std::to_string(freq_dds_tx_hz_));
|
||||
params_dds.push_back("out_altvoltage2_TX1_Q_F1_phase=" +
|
||||
std::to_string(phase_dds_deg_ * 1000.0 + 270000.0));
|
||||
params_dds.push_back("out_altvoltage2_TX1_Q_F1_scale=" +
|
||||
std::to_string(scale_dds_));
|
||||
params_dds.push_back("out_altvoltage2_TX1_Q_F1_raw=1");
|
||||
|
||||
//DDS TX CH1 I (tone #1)
|
||||
// params_dds.push_back("out_altvoltage4_TX2_I_F1_frequency=" +
|
||||
// params_dds.push_back("out_altvoltage0_TX1_I_F1_frequency=" +
|
||||
// std::to_string(freq_dds_tx_hz_));
|
||||
// params_dds.push_back("out_altvoltage4_TX2_I_F1_phase=" +
|
||||
// params_dds.push_back("out_altvoltage0_TX1_I_F1_phase=" +
|
||||
// std::to_string(phase_dds_deg_ * 1000.0));
|
||||
// params_dds.push_back("out_altvoltage4_TX2_I_F1_scale=" +
|
||||
// params_dds.push_back("out_altvoltage0_TX1_I_F1_scale=" +
|
||||
// std::to_string(scale_dds_));
|
||||
// params_dds.push_back("out_altvoltage4_TX2_I_F1_raw=1");
|
||||
// params_dds.push_back("out_altvoltage0_TX1_I_F1_raw=1");
|
||||
// //DDS TX CH1 Q (tone #1)
|
||||
// params_dds.push_back("out_altvoltage6_TX2_Q_F1_frequency=" +
|
||||
// params_dds.push_back("out_altvoltage2_TX1_Q_F1_frequency=" +
|
||||
// std::to_string(freq_dds_tx_hz_));
|
||||
// params_dds.push_back("out_altvoltage6_TX2_Q_F1_phase=" +
|
||||
// params_dds.push_back("out_altvoltage2_TX1_Q_F1_phase=" +
|
||||
// std::to_string(phase_dds_deg_ * 1000.0 + 270000.0));
|
||||
// params_dds.push_back("out_altvoltage6_TX2_Q_F1_scale=" +
|
||||
// params_dds.push_back("out_altvoltage2_TX1_Q_F1_scale=" +
|
||||
// std::to_string(scale_dds_));
|
||||
// params_dds.push_back("out_altvoltage6_TX2_Q_F1_raw=1");
|
||||
// params_dds.push_back("out_altvoltage2_TX1_Q_F1_raw=1");
|
||||
|
||||
//DDS TX CH2 I (tone #1)
|
||||
params_dds.push_back("out_altvoltage4_TX2_I_F1_frequency=" +
|
||||
std::to_string(freq_dds_tx_hz_));
|
||||
params_dds.push_back("out_altvoltage4_TX2_I_F1_phase=" +
|
||||
std::to_string(phase_dds_deg_ * 1000.0));
|
||||
params_dds.push_back("out_altvoltage4_TX2_I_F1_scale=" +
|
||||
std::to_string(scale_dds_));
|
||||
params_dds.push_back("out_altvoltage4_TX2_I_F1_raw=1");
|
||||
//DDS TX CH2 Q (tone #1)
|
||||
params_dds.push_back("out_altvoltage6_TX2_Q_F1_frequency=" +
|
||||
std::to_string(freq_dds_tx_hz_));
|
||||
params_dds.push_back("out_altvoltage6_TX2_Q_F1_phase=" +
|
||||
std::to_string(phase_dds_deg_ * 1000.0 + 270000.0));
|
||||
params_dds.push_back("out_altvoltage6_TX2_Q_F1_scale=" +
|
||||
std::to_string(scale_dds_));
|
||||
params_dds.push_back("out_altvoltage6_TX2_Q_F1_raw=1");
|
||||
|
||||
configure_params(dds_dev, params_dds);
|
||||
|
||||
@@ -511,10 +520,11 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_,
|
||||
std::cout << "Configuring DDS Local Oscillator generation. LO Freq. is " << delta_freq_hz << " [Hz]\n";
|
||||
PlutoTxEnable(true);
|
||||
config_ad9361_dds(delta_freq_hz,
|
||||
30,
|
||||
100000,
|
||||
0,
|
||||
0,
|
||||
0.9,
|
||||
0);
|
||||
0,
|
||||
2);
|
||||
std::cout << "Configuring DDS Local Oscillator generation DONE\n";
|
||||
}
|
||||
else
|
||||
@@ -633,6 +643,7 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_,
|
||||
// }
|
||||
|
||||
std::cout << "AD936x Front-end configuration summary: \n";
|
||||
std::cout << "RF frequency tunned in AD936x: " << freq_ << " [Hz]\n";
|
||||
std::cout << "Baseband sampling frequency: " << sample_rate_sps << " [SPS]\n";
|
||||
std::cout << "RX chain gain: " << rf_gain_rx0_ << " [dB][only valid in manual mode]\n";
|
||||
std::cout << "RX chain gain mode: " << gain_mode_rx0_ << "\n";
|
||||
@@ -812,13 +823,13 @@ void ad936x_iio_custom::stop_record()
|
||||
{
|
||||
receive_samples = false;
|
||||
|
||||
if (capture_time_thread.joinable() == true)
|
||||
if (capture_samples_thread.joinable() == true)
|
||||
{
|
||||
std::cout << "Joining sample cature thread...\n";
|
||||
capture_samples_thread.join();
|
||||
}
|
||||
|
||||
if (capture_time_thread.joinable() == true)
|
||||
if (overflow_monitor_thread.joinable() == true)
|
||||
{
|
||||
std::cout << "Joining overflow monitor thread...\n";
|
||||
overflow_monitor_thread.join();
|
||||
@@ -1153,7 +1164,7 @@ void ad936x_iio_custom::capture(const std::vector<std::string> &channels)
|
||||
unsigned long items_in_buffer;
|
||||
std::cerr << "Enter capture loop...\n";
|
||||
int ret;
|
||||
int bytes_per_channel = static_cast<int>(channels.size()) * 2; //each channel has two items in channels vector (I,Q). Each component has two bytes.
|
||||
int bytes_to_interleaved_iq_samples = n_channels * sizeof(int16_t);
|
||||
while (receive_samples == true)
|
||||
{
|
||||
free_buffers.wait_and_pop(current_buffer);
|
||||
@@ -1173,21 +1184,16 @@ void ad936x_iio_custom::capture(const std::vector<std::string> &channels)
|
||||
return;
|
||||
}
|
||||
}
|
||||
memcpy(¤t_samples->buffer[0], iio_buffer_start(rxbuf), ret);
|
||||
|
||||
// Demultiplex the samples of a given channel
|
||||
int n_ch = 0;
|
||||
for (auto it = std::begin(channel_list); it != std::end(channel_list); ++it)
|
||||
{
|
||||
current_samples->n_bytes[n_ch] = iio_channel_read_raw(*it, rxbuf, ¤t_samples->buffer[n_ch][0], IIO_MAX_BYTES_PER_CHANNEL);
|
||||
current_samples->n_samples[n_ch] = current_samples->n_bytes[n_ch] / sizeof(short);
|
||||
n_ch++;
|
||||
}
|
||||
items_in_buffer = static_cast<unsigned long>(ret) / bytes_to_interleaved_iq_samples;
|
||||
|
||||
// old, valid only for one channel
|
||||
//memcpy(¤t_samples->buffer[0], iio_buffer_start(rxbuf), ret);
|
||||
|
||||
if (current_samples->n_bytes[0] == 0) return;
|
||||
if (items_in_buffer == 0) return;
|
||||
|
||||
current_samples->n_channels = n_channels;
|
||||
current_samples->n_interleaved_iq_samples = items_in_buffer;
|
||||
current_samples->n_bytes = ret;
|
||||
current_samples->step_bytes = iio_buffer_step(rxbuf);
|
||||
used_buffers.push(current_buffer);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,8 @@ private:
|
||||
double tx_attenuation_db_,
|
||||
int64_t freq_dds_tx_hz_,
|
||||
double scale_dds_,
|
||||
double phase_dds_deg_);
|
||||
double phase_dds_deg_,
|
||||
int channel);
|
||||
|
||||
void get_PPS_timestamp();
|
||||
void capture(const std::vector<std::string> &channels);
|
||||
|
||||
@@ -18,9 +18,8 @@
|
||||
|
||||
ad936x_iio_samples::ad936x_iio_samples()
|
||||
{
|
||||
for (int n = 0; n < IIO_MAX_CH; n++)
|
||||
{
|
||||
n_bytes[n] = 0;
|
||||
n_samples[n] = 0;
|
||||
}
|
||||
n_bytes = 0;
|
||||
n_interleaved_iq_samples = 0;
|
||||
step_bytes = 0;
|
||||
n_channels = 0;
|
||||
}
|
||||
|
||||
@@ -18,12 +18,9 @@
|
||||
#ifndef SRC_LIBS_ad936x_iio_samples_H_
|
||||
#define SRC_LIBS_ad936x_iio_samples_H_
|
||||
|
||||
#define IIO_DEFAULTAD936XAPIFIFOSIZE_SAMPLES 32768 * 2
|
||||
#define IIO_DEFAULTAD936XAPIFIFOSIZE_SAMPLES 32768
|
||||
|
||||
#define IIO_INPUTRAMFIFOSIZE 512
|
||||
|
||||
#define IIO_MAX_CH 4
|
||||
#define IIO_MAX_BYTES_PER_CHANNEL IIO_DEFAULTAD936XAPIFIFOSIZE_SAMPLES * 2 * 2 //(2-bytes per I + 2-bytes per Q)
|
||||
#define IIO_INPUTRAMFIFOSIZE 256
|
||||
|
||||
#include <memory>
|
||||
#include <stdint.h>
|
||||
@@ -33,9 +30,11 @@ class ad936x_iio_samples
|
||||
{
|
||||
public:
|
||||
ad936x_iio_samples();
|
||||
uint32_t n_bytes[IIO_MAX_CH];
|
||||
uint32_t n_samples[IIO_MAX_CH];
|
||||
int16_t buffer[IIO_MAX_CH][IIO_DEFAULTAD936XAPIFIFOSIZE_SAMPLES * 2]; //16 bits I,Q samples buffers
|
||||
uint32_t n_bytes;
|
||||
uint32_t n_interleaved_iq_samples;
|
||||
uint16_t n_channels;
|
||||
uint16_t step_bytes;
|
||||
char buffer[IIO_DEFAULTAD936XAPIFIFOSIZE_SAMPLES * 4 * 4]; //max 16 bits samples per buffer (4 channels, 2-bytes per I + 2-bytes per Q)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user