SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
deviceplutosdrbox.cpp
Go to the documentation of this file.
1 // Copyright (C) 2017 Edouard Griffiths, F4EXB //
3 // //
4 // This program is free software; you can redistribute it and/or modify //
5 // it under the terms of the GNU General Public License as published by //
6 // the Free Software Foundation as version 3 of the License, or //
7 // (at your option) any later version. //
8 // //
9 // This program is distributed in the hope that it will be useful, //
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
12 // GNU General Public License V3 for more details. //
13 // //
14 // You should have received a copy of the GNU General Public License //
15 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
17 
18 #include <iostream>
19 #include <cstdio>
20 #include <cstring>
21 #include <regex>
22 #include <iio.h>
23 #include <boost/lexical_cast.hpp>
24 #include <QtGlobal>
25 
26 #include "dsp/dsptypes.h"
27 #include "dsp/wfir.h"
28 #include "deviceplutosdr.h"
29 #include "deviceplutosdrbox.h"
30 
31 DevicePlutoSDRBox::DevicePlutoSDRBox(const std::string& uri) :
32  m_devSampleRate(0),
33  m_LOppmTenths(0),
34  m_lpfFIREnable(false),
35  m_lpfFIRBW(100.0f),
36  m_lpfFIRlog2Decim(0),
37  m_lpfFIRRxGain(0),
38  m_lpfFIRTxGain(0),
39  m_ctx(0),
40  m_devPhy(0),
41  m_devRx(0),
42  m_devTx(0),
43  m_chnRx0(0),
44  m_chnTx0i(0),
45  m_chnTx0q(0),
46  m_rxBuf(0),
47  m_txBuf(0),
48  m_xoInitial(0),
49  m_temp(0.0f)
50 {
51  m_ctx = iio_create_context_from_uri(uri.c_str());
52 
53  if (m_ctx)
54  {
55  m_devPhy = iio_context_find_device(m_ctx, "ad9361-phy");
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");
58  }
59 
61 
62  if (m_valid) {
63  getXO();
64 // int nb_channels = iio_device_get_channels_count(m_devRx);
65 // for (int i = 0; i < nb_channels; i++) {
66 // iio_channel_disable(iio_device_get_channel(m_devRx, i));
67 // }
68 // nb_channels = iio_device_get_channels_count(m_devTx);
69 // for (int i = 0; i < nb_channels; i++) {
70 // iio_channel_disable(iio_device_get_channel(m_devTx, i));
71 // }
72  }
73 }
74 
76 {
79  closeRx();
80  closeTx();
81  if (m_ctx) { iio_context_destroy(m_ctx); }
82 }
83 
84 bool DevicePlutoSDRBox::probeURI(const std::string& uri)
85 {
86  bool retVal;
87  struct iio_context *ctx;
88 
89  ctx = iio_create_context_from_uri(uri.c_str());
90  retVal = (ctx != 0);
91 
92  if (ctx) {
93  iio_context_destroy(ctx);
94  }
95 
96  return retVal;
97 }
98 
100  const std::vector<std::string>& params)
101 {
102  iio_device *dev;
103 
104  switch (devType)
105  {
106  case DEVICE_PHY:
107  dev = m_devPhy;
108  break;
109  case DEVICE_RX:
110  dev = m_devRx;
111  break;
112  case DEVICE_TX:
113  dev = m_devTx;
114  break;
115  default:
116  dev = m_devPhy;
117  break;
118  }
119 
120  for (std::vector<std::string>::const_iterator it = params.begin(); it != params.end(); ++it)
121  {
122  struct iio_channel *chn = 0;
123  const char *attr = 0;
124  std::size_t pos;
125  int ret;
126  int type;
127 
128  pos = it->find('=');
129 
130  if (pos == std::string::npos)
131  {
132  std::cerr << "DevicePlutoSDRBox::set_params: Misformed line: " << *it << std::endl;
133  continue;
134  }
135 
136  std::string key = it->substr(0, pos);
137  std::string val = it->substr(pos + 1, std::string::npos);
138 
139  ret = iio_device_identify_filename(dev, key.c_str(), &chn, &attr);
140 
141  if (ret)
142  {
143  std::cerr << "DevicePlutoSDRBox::set_params: Parameter not recognized: " << key << std::endl;
144  continue;
145  }
146 
147  if (chn) {
148  ret = iio_channel_attr_write(chn, attr, val.c_str());
149  type = 0;
150  } else if (iio_device_find_attr(dev, attr)) {
151  ret = iio_device_attr_write(dev, attr, val.c_str());
152  type = 1;
153  } else {
154  ret = iio_device_debug_attr_write(dev, attr, val.c_str());
155  type = 2;
156  }
157 
158  if (ret < 0)
159  {
160  std::string item;
161  char errstr[256];
162 
163  switch (type)
164  {
165  case 0:
166  item = "channel";
167  break;
168  case 1:
169  item = "device";
170  break;
171  case 2:
172  item = "debug";
173  break;
174  default:
175  item = "unknown";
176  break;
177  }
178  iio_strerror(-ret, errstr, 255);
179  std::cerr << "DevicePlutoSDRBox::set_params: Unable to write " << item << " attribute " << key << "=" << val << ": " << errstr << " (" << ret << ") " << std::endl;
180  }
181  else
182  {
183  std::cerr << "DevicePlutoSDRBox::set_params: set attribute " << key << "=" << val << ": " << ret << std::endl;
184  }
185  }
186 }
187 
188 bool DevicePlutoSDRBox::get_param(DeviceType devType, const std::string &param, std::string &value)
189 {
190  struct iio_channel *chn = 0;
191  const char *attr = 0;
192  char valuestr[256];
193  int ret;
194  ssize_t nchars;
195  iio_device *dev;
196 
197  switch (devType)
198  {
199  case DEVICE_PHY:
200  dev = m_devPhy;
201  break;
202  case DEVICE_RX:
203  dev = m_devRx;
204  break;
205  case DEVICE_TX:
206  dev = m_devTx;
207  break;
208  default:
209  dev = m_devPhy;
210  break;
211  }
212 
213  ret = iio_device_identify_filename(dev, param.c_str(), &chn, &attr);
214 
215  if (ret)
216  {
217  std::cerr << "DevicePlutoSDRBox::get_param: Parameter not recognized: " << param << std::endl;
218  return false;
219  }
220 
221  if (chn) {
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);
225  } else {
226  nchars = iio_device_debug_attr_read(dev, attr, valuestr, 256);
227  }
228 
229  if (nchars < 0)
230  {
231  std::cerr << "DevicePlutoSDRBox::get_param: Unable to read attribute " << param << ": " << nchars << std::endl;
232  return false;
233  }
234  else
235  {
236  value.assign(valuestr);
237  return true;
238  }
239 }
240 
241 void DevicePlutoSDRBox::setFilter(const std::string &filterConfigStr)
242 {
243  int ret;
244 
245  ret = iio_device_attr_write_raw(m_devPhy, "filter_fir_config", filterConfigStr.c_str(), filterConfigStr.size());
246 
247  if (ret < 0)
248  {
249  std::cerr << "DevicePlutoSDRBox::set_filter: Unable to set: " << filterConfigStr << ": " << ret << std::endl;
250  }
251 }
252 
254 {
255  if (!m_valid) { return false; }
256 
257  if (!m_chnRx0) {
258  m_chnRx0 = iio_device_find_channel(m_devRx, "voltage0", false);
259  }
260 
261  if (m_chnRx0) {
262  iio_channel_enable(m_chnRx0);
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",
265  df->length,
266  df->bits,
267  df->shift,
268  df->is_signed ? "true" : "false",
269  df->is_be ? "true" : "false",
270  df->with_scale? "true" : "false",
271  df->scale,
272  df->repeat);
273  return true;
274  } else {
275  std::cerr << "DevicePlutoSDRBox::openRx: failed" << std::endl;
276  return false;
277  }
278 }
279 
281 {
282  if (!m_valid) { return false; }
283 
284  if (!m_chnTx0i) {
285  m_chnTx0i = iio_device_find_channel(m_devTx, "voltage0", true);
286  }
287 
288  if (m_chnTx0i) {
289  iio_channel_enable(m_chnTx0i);
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",
292  df->length,
293  df->bits,
294  df->shift,
295  df->is_signed ? "true" : "false",
296  df->is_be ? "true" : "false",
297  df->with_scale? "true" : "false",
298  df->scale,
299  df->repeat);
300  } else {
301  std::cerr << "DevicePlutoSDRBox::openTx: failed to open I channel" << std::endl;
302  return false;
303  }
304 
305  if (!m_chnTx0q) {
306  m_chnTx0q = iio_device_find_channel(m_devTx, "voltage1", true);
307  }
308 
309  if (m_chnTx0q) {
310  iio_channel_enable(m_chnTx0q);
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",
313  df->length,
314  df->bits,
315  df->shift,
316  df->is_signed ? "true" : "false",
317  df->is_be ? "true" : "false",
318  df->with_scale? "true" : "false",
319  df->scale,
320  df->repeat);
321  return true;
322  } else {
323  std::cerr << "DevicePlutoSDRBox::openTx: failed to open Q channel" << std::endl;
324  return false;
325  }
326 }
327 
329 {
330  if (m_chnRx0) { iio_channel_disable(m_chnRx0); }
331 }
332 
334 {
335  if (m_chnTx0i) { iio_channel_disable(m_chnTx0i); }
336  if (m_chnTx0q) { iio_channel_disable(m_chnTx0q); }
337 }
338 
339 struct iio_buffer *DevicePlutoSDRBox::createRxBuffer(unsigned int size, bool cyclic)
340 {
341  if (m_devRx) {
342  m_rxBuf = iio_device_create_buffer(m_devRx, size, cyclic ? '\1' : '\0');
343  } else {
344  m_rxBuf = 0;
345  }
346 
347  return m_rxBuf;
348 }
349 
350 struct iio_buffer *DevicePlutoSDRBox::createTxBuffer(unsigned int size, bool cyclic)
351 {
352  if (m_devTx) {
353  m_txBuf = iio_device_create_buffer(m_devTx, size, cyclic ? '\1' : '\0');
354  } else {
355  m_txBuf = 0;
356  }
357 
358  return m_txBuf;
359 }
360 
362 {
363  if (m_rxBuf) {
364  iio_buffer_destroy(m_rxBuf);
365  m_rxBuf = 0;
366  }
367 }
368 
370 {
371  if (m_txBuf) {
372  iio_buffer_destroy(m_txBuf);
373  m_txBuf = 0;
374  }
375 }
376 
378 {
379  if (m_devRx) {
380  return iio_device_get_sample_size(m_devRx);
381  } else {
382  return 0;
383  }
384 }
385 
387 {
388  if (m_devTx) {
389  return iio_device_get_sample_size(m_devTx);
390  } else {
391  return 0;
392  }
393 }
394 
396 {
397  if (m_rxBuf) {
398  return iio_buffer_refill(m_rxBuf);
399  } else {
400  return 0;
401  }
402 }
403 
405 {
406  if (m_txBuf) {
407  return iio_buffer_push(m_txBuf);
408  } else {
409  return 0;
410  }
411 }
412 
414 {
415  if (m_rxBuf) {
416  return iio_buffer_step(m_rxBuf);
417  } else {
418  return 0;
419  }
420 }
421 
423 {
424  if (m_rxBuf) {
425  return (char *) iio_buffer_end(m_rxBuf);
426  } else {
427  return 0;
428  }
429 }
430 
432 {
433  if (m_rxBuf) {
434  return (char *) iio_buffer_first(m_rxBuf, m_chnRx0);
435  } else {
436  return 0;
437  }
438 }
439 
441 {
442  if (m_txBuf) {
443  return iio_buffer_step(m_txBuf);
444  } else {
445  return 0;
446  }
447 }
448 
450 {
451  if (m_txBuf) {
452  return (char *) iio_buffer_end(m_txBuf);
453  } else {
454  return 0;
455  }
456 }
457 
459 {
460  if (m_txBuf) {
461  return (char *) iio_buffer_first(m_txBuf, m_chnTx0i);
462  } else {
463  return 0;
464  }
465 }
466 
468 {
469  if (m_chnTx0i) {
470  iio_channel_convert_inverse(m_chnTx0i, &dst[0], &src[0]);
471  }
472  if (m_chnTx0q) {
473  iio_channel_convert_inverse(m_chnTx0q, &dst[1], &src[1]);
474  }
475 }
476 
478 {
479  std::string srStr;
480 
481  if (get_param(DEVICE_PHY, "rx_path_rates", srStr)) {
482  qDebug("DevicePlutoSDRBox::getRxSampleRates: %s", srStr.c_str());
483  return parseSampleRates(srStr, sampleRates);
484  } else {
485  return false;
486  }
487 }
488 
490 {
491  std::string srStr;
492 
493  if (get_param(DEVICE_PHY, "tx_path_rates", srStr)) {
494  return parseSampleRates(srStr, sampleRates);
495  } else {
496  return false;
497  }
498 }
499 
500 bool DevicePlutoSDRBox::parseSampleRates(const std::string& rateStr, SampleRates& sampleRates)
501 {
502  // Rx: "BBPLL:983040000 ADC:245760000 R2:122880000 R1:61440000 RF:30720000 RXSAMP:30720000"
503  // Tx: "BBPLL:983040000 DAC:122880000 T2:122880000 T1:61440000 TF:30720000 TXSAMP:30720000"
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;
508 
509  if (desc_match.size() == 7)
510  {
511  try
512  {
513  sampleRates.m_bbRateHz = boost::lexical_cast<uint32_t>(desc_match[1]);
514  sampleRates.m_addaConnvRate = boost::lexical_cast<uint32_t>(desc_match[2]);
515  sampleRates.m_hb3Rate = boost::lexical_cast<uint32_t>(desc_match[3]);
516  sampleRates.m_hb2Rate = boost::lexical_cast<uint32_t>(desc_match[4]);
517  sampleRates.m_hb1Rate = boost::lexical_cast<uint32_t>(desc_match[5]);
518  sampleRates.m_firRate = boost::lexical_cast<uint32_t>(desc_match[6]);
519  return true;
520  }
521  catch (const boost::bad_lexical_cast &e)
522  {
523  qWarning("DevicePlutoSDRBox::parseSampleRates: bad conversion to numeric");
524  return false;
525  }
526  }
527  else
528  {
529  return false;
530  }
531 }
532 
534 {
535  char buff[100];
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));
541  set_params(DEVICE_PHY, params);
542  m_devSampleRate = sampleRate;
543 }
544 
552 void DevicePlutoSDRBox::setFIR(uint32_t sampleRate, uint32_t log2IntDec, DeviceUse use, uint32_t bw, int gain)
553 {
554  SampleRates sampleRates;
555  std::ostringstream ostr;
556 
557  uint32_t nbTaps;
558  double normalizedBW;
559  uint32_t intdec = 1<<(log2IntDec > 2 ? 2 : log2IntDec);
560 
561  // update gain parameter
562 
563  if (use == USE_RX) {
564  m_lpfFIRRxGain = gain;
565  } else {
566  m_lpfFIRTxGain = gain;
567  }
568 
569  // set a dummy minimal filter first to get the sample rates right
570 
571  setFIREnable(false); // disable first
572 
573  formatFIRHeader(ostr, intdec);
574  formatFIRCoefficients(ostr, 16, 0.5);
575  setFilter(ostr.str());
576  ostr.str(""); // reset string stream
577 
578  setFIREnable(true); // re-enable
579  setSampleRate(sampleRate); // set to new sample rate
580 
581  if (!getRxSampleRates(sampleRates)) {
582  return;
583  }
584 
585  setFIREnable(false); // disable again
586 
587  uint32_t nbGroups = sampleRates.m_addaConnvRate / 16;
588  nbTaps = nbGroups*8 > 128 ? 128 : nbGroups*8;
589  nbTaps = intdec == 1 ? (nbTaps > 64 ? 64 : nbTaps) : nbTaps;
590  normalizedBW = ((float) bw) / sampleRates.m_hb1Rate;
591  normalizedBW = normalizedBW < DevicePlutoSDR::firBWLowLimitFactor ?
594 
595  qDebug("DevicePlutoSDRBox::setFIR: intdec: %u gain: %d nbTaps: %u BWin: %u BW: %f (%f)",
596  intdec,
597  gain,
598  nbTaps,
599  bw,
600  normalizedBW*sampleRates.m_hb1Rate,
601  normalizedBW);
602 
603  // set the right filter
604 
605  formatFIRHeader(ostr, intdec);
606  formatFIRCoefficients(ostr, nbTaps, normalizedBW);
607  setFilter(ostr.str());
608 
609  m_lpfFIRlog2Decim = log2IntDec;
610  m_lpfFIRBW = bw;
611 
612  // enable and set sample rate will be done by the caller
613 }
614 
616 {
617  char buff[100];
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));
621  set_params(DEVICE_PHY, params);
622  m_lpfFIREnable = enable;
623 }
624 
626 {
627  char buff[100];
628  std::vector<std::string> params;
629  int64_t newXO = m_xoInitial + ((m_xoInitial*ppmTenths) / 10000000L);
630  snprintf(buff, sizeof(buff), "xo_correction=%ld", (long int) newXO);
631  params.push_back(std::string(buff));
632  set_params(DEVICE_PHY, params);
633  m_LOppmTenths = ppmTenths;
634 }
635 
636 void DevicePlutoSDRBox::formatFIRHeader(std::ostringstream& ostr,uint32_t intdec)
637 {
638  ostr << "RX 3 GAIN " << m_lpfFIRRxGain << " DEC " << intdec << std::endl;
639  ostr << "TX 3 GAIN " << m_lpfFIRTxGain << " INT " << intdec << std::endl;
640 }
641 
642 void DevicePlutoSDRBox::formatFIRCoefficients(std::ostringstream& ostr, uint32_t nbTaps, double normalizedBW)
643 {
644  double *fcoeffs = new double[nbTaps];
645  WFIR::BasicFIR(fcoeffs, nbTaps, WFIR::LPF, normalizedBW, 0.0, normalizedBW < 0.2 ? WFIR::wtHAMMING : WFIR::wtBLACKMAN_HARRIS, 0.0);
646 
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;
649  }
650 
651  delete[] fcoeffs;
652 }
653 
655 {
656  std::string valueStr;
657  get_param(DEVICE_PHY, "xo_correction", valueStr);
658  try
659  {
660  m_xoInitial = boost::lexical_cast<quint64>(valueStr);
661  qDebug("DevicePlutoSDRBox::getXO: %ld", m_xoInitial);
662  }
663  catch (const boost::bad_lexical_cast &e)
664  {
665  qWarning("DevicePlutoSDRBox::getXO: cannot get initial XO correction");
666  }
667 }
668 
669 bool DevicePlutoSDRBox::getRxGain(int& gaindB, unsigned int chan)
670 {
671  chan = chan % 2;
672  char buff[30];
673  snprintf(buff, sizeof(buff), "in_voltage%d_hardwaregain", chan);
674  std::string gainStr;
675  get_param(DEVICE_PHY, buff, gainStr);
676 
677  std::regex gain_regex("(.+)\\.(.+) dB");
678  std::smatch gain_match;
679  std::regex_search(gainStr, gain_match, gain_regex);
680 
681  if (gain_match.size() == 3)
682  {
683  try
684  {
685  gaindB = boost::lexical_cast<int>(gain_match[1]);
686  return true;
687  }
688  catch (const boost::bad_lexical_cast &e)
689  {
690  qWarning("DevicePlutoSDRBox::getRxGain: bad conversion to numeric");
691  return false;
692  }
693  }
694  else
695  {
696  return false;
697  }
698 }
699 
700 bool DevicePlutoSDRBox::getRxRSSI(std::string& rssiStr, unsigned int chan)
701 {
702  chan = chan % 2;
703  char buff[20];
704  snprintf(buff, sizeof(buff), "in_voltage%d_rssi", chan);
705  return get_param(DEVICE_PHY, buff, rssiStr);
706 }
707 
708 bool DevicePlutoSDRBox::getTxRSSI(std::string& rssiStr, unsigned int chan)
709 {
710  chan = chan % 2;
711  char buff[20];
712  snprintf(buff, sizeof(buff), "out_voltage%d_rssi", chan);
713  return get_param(DEVICE_PHY, buff, rssiStr);
714 }
715 
717 {
718  // values are returned in Hz
719  qint64 stepLimit;
720  std::string rangeStr;
721 
722  char buff[50];
723  snprintf(buff, sizeof(buff), "out_altvoltage0_RX_LO_frequency_available");
724 
725  if (get_param(DEVICE_PHY, buff, rangeStr))
726  {
727  std::istringstream instream(rangeStr.substr(1, rangeStr.size() - 2));
728  instream >> minLimit >> stepLimit >> maxLimit;
729  }
730  else
731  {
734  }
735 }
736 
738 {
739  // values are returned in Hz
740  qint64 stepLimit;
741  std::string rangeStr;
742 
743  char buff[50];
744  snprintf(buff, sizeof(buff), "out_altvoltage1_TX_LO_frequency_available");
745 
746  if (get_param(DEVICE_PHY, buff, rangeStr))
747  {
748  std::istringstream instream(rangeStr.substr(1, rangeStr.size() - 2));
749  instream >> minLimit >> stepLimit >> maxLimit;
750  }
751  else
752  {
755  }
756 }
757 
759 {
760  // values are returned in Hz of RF (complex channel) bandwidth
761  qint32 stepLimit;
762  std::string rangeStr;
763 
764  char buff[50];
765  snprintf(buff, sizeof(buff), "in_voltage_rf_bandwidth_available");
766 
767  if (get_param(DEVICE_PHY, buff, rangeStr))
768  {
769  std::istringstream instream(rangeStr.substr(1, rangeStr.size() - 2));
770  instream >> minLimit >> stepLimit >> maxLimit;
771  }
772  else
773  {
776  }
777 }
778 
780 {
781  // values are returned in Hz
782  qint32 stepLimit;
783  std::string rangeStr;
784 
785  char buff[50];
786  snprintf(buff, sizeof(buff), "out_voltage_rf_bandwidth_available");
787 
788  if (get_param(DEVICE_PHY, buff, rangeStr))
789  {
790  std::istringstream instream(rangeStr.substr(1, rangeStr.size() - 2));
791  instream >> minLimit >> stepLimit >> maxLimit;
792  }
793  else
794  {
797  }
798 }
799 
800 
802 {
803  std::string temp_mC_str;
804 
805  if (get_param(DEVICE_PHY, "in_temp0_input", temp_mC_str))
806  {
807  try
808  {
809  uint32_t temp_mC = boost::lexical_cast<uint32_t>(temp_mC_str);
810  m_temp = temp_mC / 1000.0;
811  return true;
812  }
813  catch (const boost::bad_lexical_cast &e)
814  {
815  std::cerr << "PlutoSDRDevice::getTemp: bad conversion to numeric" << std::endl;
816  return false;
817  }
818  }
819  else
820  {
821  return false;
822  }
823 }
824 
825 bool DevicePlutoSDRBox::getRateGovernors(std::string& rateGovernors)
826 {
827  return get_param(DEVICE_PHY, "trx_rate_governor", rateGovernors);
828 }
short int16_t
Definition: rtptypes_win.h:43
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 &param, 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)
__int64 int64_t
Definition: rtptypes_win.h:47
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
unsigned int uint32_t
Definition: rtptypes_win.h:46
Definition: wfir.h:63
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)
int32_t i
Definition: decimators.h:244
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)
Definition: wfir.cpp:19
bool getTxSampleRates(SampleRates &sampleRates)
struct iio_buffer * m_rxBuf
void getTxLORange(uint64_t &minLimit, uint64_t &maxLimit)
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.
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 > &params)
unsigned __int64 uint64_t
Definition: rtptypes_win.h:48