23 #include <boost/lexical_cast.hpp>    34         m_lpfFIREnable(false),
    51     m_ctx = iio_create_context_from_uri(uri.c_str());
    56         m_devRx = iio_context_find_device(
m_ctx, 
"cf-ad9361-lpc");
    57         m_devTx = iio_context_find_device(
m_ctx, 
"cf-ad9361-dds-core-lpc");
    87     struct iio_context *ctx;
    89     ctx = iio_create_context_from_uri(uri.c_str());
    93         iio_context_destroy(ctx);
   100         const std::vector<std::string>& params)
   120     for (std::vector<std::string>::const_iterator it = params.begin(); it != params.end(); ++it)
   122         struct iio_channel *chn = 0;
   123         const char *attr = 0;
   130         if (pos == std::string::npos)
   132             std::cerr << 
"DevicePlutoSDRBox::set_params: Misformed line: " << *it << std::endl;
   136         std::string key = it->substr(0, pos);
   137         std::string val = it->substr(pos + 1, std::string::npos);
   139         ret = iio_device_identify_filename(dev, key.c_str(), &chn, &attr);
   143             std::cerr << 
"DevicePlutoSDRBox::set_params: Parameter not recognized: " << key << std::endl;
   148             ret = iio_channel_attr_write(chn, attr, val.c_str());
   150         } 
else if (iio_device_find_attr(dev, attr)) {
   151             ret = iio_device_attr_write(dev, attr, val.c_str());
   154             ret = iio_device_debug_attr_write(dev, attr, val.c_str());
   178             iio_strerror(-ret, errstr, 255);
   179             std::cerr << 
"DevicePlutoSDRBox::set_params: Unable to write " << item << 
" attribute " << key << 
"=" << val << 
": " << errstr << 
" (" << ret << 
") " << std::endl;
   183             std::cerr << 
"DevicePlutoSDRBox::set_params: set attribute " << key << 
"=" << val << 
": " << ret << std::endl;
   190     struct iio_channel *chn = 0;
   191     const char *attr = 0;
   213     ret = iio_device_identify_filename(dev, param.c_str(), &chn, &attr);
   217         std::cerr << 
"DevicePlutoSDRBox::get_param: Parameter not recognized: " << param << std::endl;
   222         nchars = iio_channel_attr_read(chn, attr, valuestr, 256);
   223     } 
else if (iio_device_find_attr(dev, attr)) {
   224         nchars = iio_device_attr_read(dev, attr, valuestr, 256);
   226         nchars = iio_device_debug_attr_read(dev, attr, valuestr, 256);
   231         std::cerr << 
"DevicePlutoSDRBox::get_param: Unable to read attribute " << param <<  
": " << nchars << std::endl;
   236         value.assign(valuestr);
   245     ret = iio_device_attr_write_raw(
m_devPhy, 
"filter_fir_config", filterConfigStr.c_str(), filterConfigStr.size());
   249         std::cerr << 
"DevicePlutoSDRBox::set_filter: Unable to set: " <<  filterConfigStr <<  
": " << ret << std::endl;
   255     if (!
m_valid) { 
return false; }
   263         const struct iio_data_format *df = iio_channel_get_data_format(
m_chnRx0);
   264         qDebug(
"DevicePlutoSDRBox::openRx: length: %u bits: %u shift: %u signed: %s be: %s with_scale: %s scale: %lf repeat: %u",
   268                 df->is_signed ? 
"true" : 
"false",
   269                 df->is_be ? 
"true" : 
"false",
   270                 df->with_scale? 
"true" : 
"false",
   275         std::cerr << 
"DevicePlutoSDRBox::openRx: failed" << std::endl;
   282     if (!
m_valid) { 
return false; }
   290         const struct iio_data_format *df = iio_channel_get_data_format(
m_chnTx0i);
   291         qDebug(
"DevicePlutoSDRBox::openTx: channel I: length: %u bits: %u shift: %u signed: %s be: %s with_scale: %s scale: %lf repeat: %u",
   295                 df->is_signed ? 
"true" : 
"false",
   296                 df->is_be ? 
"true" : 
"false",
   297                 df->with_scale? 
"true" : 
"false",
   301         std::cerr << 
"DevicePlutoSDRBox::openTx: failed to open I channel" << std::endl;
   311         const struct iio_data_format *df = iio_channel_get_data_format(
m_chnTx0q);
   312         qDebug(
"DevicePlutoSDRBox::openTx: channel Q: length: %u bits: %u shift: %u signed: %s be: %s with_scale: %s scale: %lf repeat: %u",
   316                 df->is_signed ? 
"true" : 
"false",
   317                 df->is_be ? 
"true" : 
"false",
   318                 df->with_scale? 
"true" : 
"false",
   323         std::cerr << 
"DevicePlutoSDRBox::openTx: failed to open Q channel" << std::endl;
   342         m_rxBuf = iio_device_create_buffer(
m_devRx, size, cyclic ? 
'\1' : 
'\0');
   353         m_txBuf =  iio_device_create_buffer(
m_devTx, size, cyclic ? 
'\1' : 
'\0');
   380         return iio_device_get_sample_size(
m_devRx);
   389         return iio_device_get_sample_size(
m_devTx);
   398         return iio_buffer_refill(
m_rxBuf);
   407         return iio_buffer_push(
m_txBuf);
   416         return iio_buffer_step(
m_rxBuf);
   425         return (
char *) iio_buffer_end(
m_rxBuf);
   443         return iio_buffer_step(
m_txBuf);
   452         return (
char *) iio_buffer_end(
m_txBuf);
   470         iio_channel_convert_inverse(
m_chnTx0i, &dst[0], &src[0]);
   473         iio_channel_convert_inverse(
m_chnTx0q, &dst[1], &src[1]);
   482         qDebug(
"DevicePlutoSDRBox::getRxSampleRates: %s", srStr.c_str());
   504     std::regex desc_regex(
"BBPLL:(.+) ..C:(.+) .2:(.+) .1:(.+) .F:(.+) .XSAMP:(.+)");
   505     std::smatch desc_match;
   506     std::regex_search(rateStr, desc_match, desc_regex);
   507     std::string valueStr;
   509     if (desc_match.size() == 7)
   521         catch (
const boost::bad_lexical_cast &e)
   523             qWarning(
"DevicePlutoSDRBox::parseSampleRates: bad conversion to numeric");
   536     std::vector<std::string> params;
   537     snprintf(buff, 
sizeof(buff), 
"in_voltage_sampling_frequency=%d", sampleRate);
   538     params.push_back(std::string(buff));
   539     snprintf(buff, 
sizeof(buff), 
"out_voltage_sampling_frequency=%d", sampleRate);
   540     params.push_back(std::string(buff));
   555     std::ostringstream ostr;
   559     uint32_t intdec = 1<<(log2IntDec > 2 ? 2 : log2IntDec);
   588     nbTaps = nbGroups*8 > 128 ? 128 : nbGroups*8;
   589     nbTaps = intdec == 1 ? (nbTaps > 64 ? 64 : nbTaps) : nbTaps;
   590     normalizedBW = ((float) bw) / sampleRates.
m_hb1Rate;
   595     qDebug(
"DevicePlutoSDRBox::setFIR: intdec: %u gain: %d nbTaps: %u BWin: %u BW: %f (%f)",
   618     std::vector<std::string> params;
   619     snprintf(buff, 
sizeof(buff), 
"in_out_voltage_filter_fir_en=%d", enable ? 1 : 0);
   620     params.push_back(std::string(buff));
   628     std::vector<std::string> params;
   630     snprintf(buff, 
sizeof(buff), 
"xo_correction=%ld", (
long int) newXO);
   631     params.push_back(std::string(buff));
   638     ostr << 
"RX 3 GAIN " << 
m_lpfFIRRxGain << 
" DEC " << intdec << std::endl;
   639     ostr << 
"TX 3 GAIN " << 
m_lpfFIRTxGain << 
" INT " << intdec << std::endl;
   644     double *fcoeffs = 
new double[nbTaps];
   647     for (
unsigned int i = 0; 
i < nbTaps; 
i++) {
   648         ostr << (
int16_t) (fcoeffs[
i] * 32768.0f) << 
", " <<  (
int16_t) (fcoeffs[
i] * 32768.0f) << std::endl;
   656     std::string valueStr;
   660         m_xoInitial = boost::lexical_cast<quint64>(valueStr);
   661         qDebug(
"DevicePlutoSDRBox::getXO: %ld", 
m_xoInitial);
   663     catch (
const boost::bad_lexical_cast &e)
   665         qWarning(
"DevicePlutoSDRBox::getXO: cannot get initial XO correction");
   673     snprintf(buff, 
sizeof(buff), 
"in_voltage%d_hardwaregain", chan);
   677     std::regex gain_regex(
"(.+)\\.(.+) dB");
   678     std::smatch gain_match;
   679     std::regex_search(gainStr, gain_match, gain_regex);
   681     if (gain_match.size() == 3)
   685             gaindB = boost::lexical_cast<
int>(gain_match[1]);
   688         catch (
const boost::bad_lexical_cast &e)
   690             qWarning(
"DevicePlutoSDRBox::getRxGain: bad conversion to numeric");
   704     snprintf(buff, 
sizeof(buff), 
"in_voltage%d_rssi", chan);
   712     snprintf(buff, 
sizeof(buff), 
"out_voltage%d_rssi", chan);
   720     std::string rangeStr;
   723     snprintf(buff, 
sizeof(buff), 
"out_altvoltage0_RX_LO_frequency_available");
   727         std::istringstream instream(rangeStr.substr(1, rangeStr.size() - 2));
   728         instream >> minLimit >> stepLimit >> maxLimit;
   741     std::string rangeStr;
   744     snprintf(buff, 
sizeof(buff), 
"out_altvoltage1_TX_LO_frequency_available");
   748         std::istringstream instream(rangeStr.substr(1, rangeStr.size() - 2));
   749         instream >> minLimit >> stepLimit >> maxLimit;
   762     std::string rangeStr;
   765     snprintf(buff, 
sizeof(buff), 
"in_voltage_rf_bandwidth_available");
   769     std::istringstream instream(rangeStr.substr(1, rangeStr.size() - 2));
   770     instream >> minLimit >> stepLimit >> maxLimit;
   783     std::string rangeStr;
   786     snprintf(buff, 
sizeof(buff), 
"out_voltage_rf_bandwidth_available");
   790         std::istringstream instream(rangeStr.substr(1, rangeStr.size() - 2));
   791         instream >> minLimit >> stepLimit >> maxLimit;
   803     std::string temp_mC_str;
   810             m_temp = temp_mC / 1000.0;
   813         catch (
const boost::bad_lexical_cast &e)
   815             std::cerr << 
"PlutoSDRDevice::getTemp: bad conversion to numeric" << std::endl;
 
bool getRxGain(int &gaindB, unsigned int chan)
 
void getRxLORange(uint64_t &minLimit, uint64_t &maxLimit)
 
struct iio_device * m_devTx
 
bool getRateGovernors(std::string &rateGovernors)
 
void setSampleRate(uint32_t sampleRate)
 
static const uint32_t bbLPRxLowLimitFreq
Analog base band Rx low pass filter lower frequency limit (Hz) 
 
static const float firBWHighLimitFactor
Factor by which the FIR working sample rate is multiplied to yield bandwidth higher limit...
 
uint32_t m_lpfFIRlog2Decim
digital lowpass FIR filter log2 of decimation factor (0..2) 
 
static const uint32_t bbLPTxHighLimitFreq
Analog base band Tx high pass filter lower frequency limit (Hz) 
 
bool parseSampleRates(const std::string &rateStr, SampleRates &sampleRates)
 
std::ptrdiff_t txBufferStep()
 
void txChannelConvert(int16_t *dst, int16_t *src)
 
float m_lpfFIRBW
digital lowpass FIR filter bandwidth (Hz) 
 
struct iio_channel * m_chnTx0i
 
DevicePlutoSDRBox(const std::string &uri)
 
static const uint64_t rxLOLowLimitFreq
Rx LO hard coded lower frequency limit (Hz) 
 
bool get_param(DeviceType devType, const std::string ¶m, std::string &value)
 
bool getTxRSSI(std::string &rssiStr, unsigned int chan)
 
void setFilter(const std::string &filterConfigStr)
 
static const uint64_t rxLOHighLimitFreq
Rx LO hard coded lower frequency limit (Hz) 
 
bool getRxRSSI(std::string &rssiStr, unsigned int chan)
 
void getbbLPRxRange(uint32_t &minLimit, uint32_t &maxLimit)
 
uint32_t m_hb3Rate
Rate of the HB3/(DEC3 or INT3) filter (Rx: out, Tx: in) - this is the HB2 working sample rate...
 
struct iio_buffer * m_txBuf
 
void setFIREnable(bool enable)
 
bool m_lpfFIREnable
enable digital lowpass FIR filter 
 
struct iio_buffer * createRxBuffer(unsigned int size, bool cyclic)
 
void setLOPPMTenths(int ppmTenths)
 
struct iio_context * m_ctx
 
bool getRxSampleRates(SampleRates &sampleRates)
 
void setFIR(uint32_t sampleRate, uint32_t intdec, DeviceUse use, uint32_t bw, int gain)
 
uint64_t m_devSampleRate
Host interface sample rate. 
 
std::ptrdiff_t rxBufferStep()
 
struct iio_device * m_devPhy
 
static void BasicFIR(double *FirCoeff, int NumTaps, TPassTypeName PassType, double OmegaC, double BW, TWindowType WindowType, double WinBeta)
 
bool getTxSampleRates(SampleRates &sampleRates)
 
struct iio_buffer * m_rxBuf
 
void getTxLORange(uint64_t &minLimit, uint64_t &maxLimit)
 
ssize_t getRxSampleSize()
 
struct iio_buffer * createTxBuffer(unsigned int size, bool cyclic)
 
static const uint32_t bbLPTxLowLimitFreq
Analog base band Tx low pass filter lower frequency limit (Hz) 
 
uint32_t m_firRate
Rate of FIR filter (Rx: out, Tx: in) - this is the host/device communication sample rate...
 
void formatFIRHeader(std::ostringstream &str, uint32_t intdec)
 
uint32_t m_hb2Rate
Rate of the HB2 filter (Rx: out, Tx: in) - this is the HB1 working sample rate. 
 
int32_t m_LOppmTenths
XO correction. 
 
void formatFIRCoefficients(std::ostringstream &str, uint32_t nbTaps, double normalizedBW)
 
static const uint64_t txLOLowLimitFreq
Tx LO hard coded lower frequency limit (Hz) 
 
struct iio_device * m_devRx
 
static const uint32_t bbLPRxHighLimitFreq
Analog base band Rx high pass filter lower frequency limit (Hz) 
 
int m_lpfFIRRxGain
digital lowpass FIR filter gain Rx side (dB) 
 
struct iio_channel * m_chnTx0q
 
static const float firBWLowLimitFactor
Factor by which the FIR working sample rate is multiplied to yield bandwidth lower limit...
 
uint32_t m_hb1Rate
Rate of the HB1 filter (Rx: out, Tx: in) - this is the FIR working sample rate. 
 
ssize_t getTxSampleSize()
 
uint32_t m_bbRateHz
Baseband PLL rate (Hz) - used internally. 
 
struct iio_channel * m_chnRx0
 
static bool probeURI(const std::string &uri)
 
uint32_t m_addaConnvRate
A/D or D/A converter rat - this is the HB3 working sample rate. 
 
static const uint64_t txLOHighLimitFreq
Tx LO hard coded lower frequency limit (Hz) 
 
void getbbLPTxRange(uint32_t &minLimit, uint32_t &maxLimit)
 
int m_lpfFIRTxGain
digital lowpass FIR filter gain Tx side (dB) 
 
void set_params(DeviceType devType, const std::vector< std::string > ¶ms)
 
unsigned __int64 uint64_t