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