diff --git a/PlutoSDR_Settings.cpp b/PlutoSDR_Settings.cpp index 7a4da0e..1694981 100644 --- a/PlutoSDR_Settings.cpp +++ b/PlutoSDR_Settings.cpp @@ -125,21 +125,159 @@ bool SoapyPlutoSDR::getFullDuplex( const int direction, const size_t channel ) c SoapySDR::ArgInfoList SoapyPlutoSDR::getSettingInfo(void) const { SoapySDR::ArgInfoList setArgs; + /* + 18 device-specific attributes + 0: calib_mode value: auto + 1: calib_mode_available value: auto manual manual_tx_quad tx_quad rf_dc_offs rssi_gain_step + 2: dcxo_tune_coarse ERROR: Operation not supported by device (-19) + 3: dcxo_tune_coarse_available value: [0 0 0] + 4: dcxo_tune_fine ERROR: Operation not supported by device (-19) + 5: dcxo_tune_fine_available value: [0 0 0] + 6: ensm_mode value: fdd + 7: ensm_mode_available value: sleep wait alert fdd pinctrl pinctrl_fdd_indep + 8: filter_fir_config value: FIR Rx: 0,0 Tx: 0,0 + 9: gain_table_config ERROR: Input/output error (-5) + 10: multichip_sync ERROR: Permission denied (-13) + 11: rssi_gain_step_error value: lna_error: 0 0 0 0\nmixer_error: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\ngain_step_calib_reg_val: 0 0 0 0 0 + 12: rx_path_rates value: BBPLL:983040004 ADC:245760001 R2:122880000 R1:61440000 RF:30720000 RXSAMP:30720000 + 13: trx_rate_governor value: nominal + 14: trx_rate_governor_available value: nominal highest_osr + 15: tx_path_rates value: BBPLL:983040004 DAC:122880000 T2:122880000 T1:61440000 TF:30720000 TXSAMP:30720000 + 16: xo_correction value: 39999976 + 17: xo_correction_available value: [39991977 1 40007975] + */ + unsigned int attrs_count = iio_device_get_attrs_count(dev); + + for (unsigned int index = 0; index < attrs_count; ++index) + { + SoapySDR::ArgInfo arg; + + const char *attr = iio_device_get_attr(dev, index); + arg.key = attr; + //arg.value = "true"; + arg.name = attr; + arg.description = attr; + //arg.type = SoapySDR::ArgInfo::BOOL; + setArgs.push_back(arg); + } return setArgs; } void SoapyPlutoSDR::writeSetting(const std::string &key, const std::string &value) { + std::lock_guard rx_lock(rx_device_mutex); + std::lock_guard tx_lock(rx_device_mutex); + iio_device_attr_write(dev, key.c_str(), value.c_str()); +} + + +std::string SoapyPlutoSDR::readSetting(const std::string &key) const +{ + std::string info; + char value[128]; + ssize_t len; + { + std::lock_guard rx_lock(rx_device_mutex); + std::lock_guard tx_lock(rx_device_mutex); + len = iio_device_attr_read(dev, key.c_str(), value, sizeof(value)); + } + if (len > 0) + { + info.assign(value, len); + } + return info; } +SoapySDR::ArgInfoList SoapyPlutoSDR::getSettingInfo(const int direction, const size_t channel) const +{ + SoapySDR::ArgInfoList setArgs; + /* + voltage2: (output) 8 channel-specific attributes found: + 0: filter_fir_en value: 0 + 1: raw value: 306 + 2: rf_bandwidth value: 18000000 + 3: rf_bandwidth_available value: [200000 1 40000000] + 4: rf_port_select_available value: A B + 5: sampling_frequency value: 30720000 + 6: sampling_frequency_available value: [2083333 1 61440000] + 7: scale value: 1.000000 + voltage2: (input) 13 channel-specific attributes found: + 0: bb_dc_offset_tracking_en value: 1 + 1: filter_fir_en value: 0 + 2: gain_control_mode_available value: manual fast_attack slow_attack hybrid + 3: offset value: 57 + 4: quadrature_tracking_en value: 1 + 5: raw value: 2004 + 6: rf_bandwidth value: 18000000 + 7: rf_bandwidth_available value: [200000 1 56000000] + 8: rf_dc_offset_tracking_en value: 1 + 9: rf_port_select_available value: A_BALANCED B_BALANCED C_BALANCED A_N A_P B_N B_P C_N C_P TX_MONITOR1 TX_MONITOR2 TX_MONITOR1_2 + 10: sampling_frequency value: 30720000 + 11: sampling_frequency_available value: [2083333 1 61440000] + 12: scale value: 0.305250 + */ + + iio_channel *chn = iio_device_find_channel(dev, "voltage2", (direction == SOAPY_SDR_TX)); + + unsigned int attrs_count = iio_channel_get_attrs_count(chn); + + for (unsigned int index = 0; index < attrs_count; ++index) + { + SoapySDR::ArgInfo arg; + + const char *attr = iio_channel_get_attr(chn, index); + arg.key = attr; + //arg.value = "true"; + arg.name = attr; + arg.description = attr; + //arg.type = SoapySDR::ArgInfo::BOOL; + setArgs.push_back(arg); + } -std::string SoapyPlutoSDR::readSetting(const std::string &key) const + return setArgs; +} + +void SoapyPlutoSDR::writeSetting(const int direction, const size_t channel, const std::string &key, const std::string &value) +{ + if (direction == SOAPY_SDR_RX) + { + std::lock_guard lock(rx_device_mutex); + iio_channel_attr_write(iio_device_find_channel(dev, "voltage2", false), key.c_str(), value.c_str()); + } + + else if (direction == SOAPY_SDR_TX) + { + std::lock_guard lock(tx_device_mutex); + iio_channel_attr_write(iio_device_find_channel(dev, "voltage2", true), key.c_str(), value.c_str()); + } +} + +std::string SoapyPlutoSDR::readSetting(const int direction, const size_t channel, const std::string &key) const { std::string info; + char value[128]; // widest attr value seen is 95 chars + ssize_t len; + + if (direction == SOAPY_SDR_RX) + { + std::lock_guard lock(rx_device_mutex); + len = iio_channel_attr_read(iio_device_find_channel(dev, "voltage2", false), key.c_str(), value, sizeof(value)); + } + + else if (direction == SOAPY_SDR_TX) + { + std::lock_guard lock(tx_device_mutex); + len = iio_channel_attr_read(iio_device_find_channel(dev, "voltage2", true), key.c_str(), value, sizeof(value)); + } + + if (len > 0) + { + info.assign(value, len); + } return info; } diff --git a/SoapyPlutoSDR.hpp b/SoapyPlutoSDR.hpp index 7f27b39..3829da0 100644 --- a/SoapyPlutoSDR.hpp +++ b/SoapyPlutoSDR.hpp @@ -197,6 +197,15 @@ class SoapyPlutoSDR : public SoapySDR::Device{ std::string readSetting(const std::string &key) const; + SoapySDR::ArgInfoList getSettingInfo(const int direction, const size_t channel) const; + + + void writeSetting(const int direction, const size_t channel, const std::string &key, const std::string &value); + + + std::string readSetting(const int direction, const size_t channel, const std::string &key) const; + + /******************************************************************* * Antenna API ******************************************************************/