/*
Copyright (C) 2015
Matthias P. Braendli, matthias.braendli@mpb.li
http://opendigitalradio.org
*/
/*
This file is part of ODR-DPD.
ODR-DPD 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.
ODR-DPD 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 ODR-DPD. If not, see .
*/
#include "OutputUHD.hpp"
#include "utils.hpp"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
OutputUHD::OutputUHD(double txgain, double rxgain, double samplerate) :
m_txgain(txgain),
m_rxgain(rxgain),
m_samplerate(samplerate)
{
uhd::set_thread_priority_safe();
string device = "master_clock_rate=32768000";
m_usrp = uhd::usrp::multi_usrp::make(device);
m_usrp->set_tx_rate(m_samplerate);
m_usrp->set_rx_rate(m_samplerate);
m_usrp->set_tx_freq(234.208e6);
double set_tx_frequency = m_usrp->get_tx_freq();
MDEBUG("OutputUHD:Actual TX frequency: %f\n", set_tx_frequency);
m_usrp->set_rx_freq(234.208e6);
double set_rx_frequency = m_usrp->get_rx_freq();
MDEBUG("OutputUHD:Actual RX frequency: %f\n", set_rx_frequency);
MDEBUG("OutputUHD:Setting TX Gain: %f ...\n", m_txgain);
m_usrp->set_tx_gain(m_txgain);
MDEBUG("OutputUHD:Actual TX Gain: %f ...\n", m_usrp->get_tx_gain());
MDEBUG("OutputUHD:Setting RX Gain: %f ...\n", m_rxgain);
m_usrp->set_rx_gain(m_rxgain);
MDEBUG("OutputUHD:Actual RX Gain: %f ...\n", m_usrp->get_rx_gain());
const double usrp_time = m_usrp->get_time_now().get_real_secs();
MDEBUG("OutputUHD: USRP time %f\n",
usrp_time);
md.start_of_burst = false;
md.end_of_burst = false;
md.has_time_spec = true;
uhd::stream_args_t stream_args("fc32"); //complex floats
myTxStream = m_usrp->get_tx_stream(stream_args);
myRxStream = m_usrp->get_rx_stream(stream_args);
uhd::stream_cmd_t stream_cmd(
uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
stream_cmd.num_samps = 0;
stream_cmd.stream_now = true;
stream_cmd.time_spec = uhd::time_spec_t();
myRxStream->issue_stream_cmd(stream_cmd);
}
size_t OutputUHD::Transmit(const complexf *samples, size_t sizeIn, double transmit_time)
{
const double tx_timeout = 20.0;
size_t usrp_max_num_samps = myTxStream->get_max_num_samps();
md.time_spec = uhd::time_spec_t(transmit_time);
size_t num_acc_samps = 0; //number of accumulated samples
while (num_acc_samps < sizeIn) {
size_t samps_to_send = std::min(sizeIn - num_acc_samps, usrp_max_num_samps);
//send a single packet
size_t num_tx_samps = myTxStream->send(
&samples[num_acc_samps],
samps_to_send, md, tx_timeout);
num_acc_samps += num_tx_samps;
md.time_spec += uhd::time_spec_t(0, num_tx_samps/m_samplerate);
}
return num_acc_samps;
}
ssize_t OutputUHD::Receive(complexf *samples, size_t sizeIn, double *first_sample_time)
{
const double rx_timeout = 20.0;
const size_t usrp_max_num_samps = myRxStream->get_max_num_samps();
const size_t samps_to_rx = std::min(sizeIn, usrp_max_num_samps);
uhd::rx_metadata_t md_rx;
ssize_t num_rx_samps = myRxStream->recv(samples, samps_to_rx, md_rx, rx_timeout);
if (md_rx.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){
MDEBUG("RX Error %s\n", md_rx.strerror().c_str());
num_rx_samps = -1;
}
else if (md_rx.has_time_spec) {
*first_sample_time = md_rx.time_spec.get_real_secs();
}
else {
*first_sample_time = 0;
}
return num_rx_samps;
}
void OutputUHD::SetTxGain(double gain)
{
m_txgain = gain;
MDEBUG("OutputUHD:Setting TX Gain: %f ...\n", m_txgain);
m_usrp->set_tx_gain(m_txgain);
MDEBUG("OutputUHD:Actual TX Gain: %f ...\n", m_usrp->get_tx_gain());
}
void OutputUHD::SetRxGain(double gain)
{
m_rxgain = gain;
MDEBUG("OutputUHD:Setting RX Gain: %f ...\n", m_rxgain);
m_usrp->set_rx_gain(m_rxgain);
MDEBUG("OutputUHD:Actual RX Gain: %f ...\n", m_usrp->get_rx_gain());
}