diff options
| -rw-r--r-- | src/output/Dexter.cpp | 172 | ||||
| -rw-r--r-- | src/output/SDR.cpp | 35 | ||||
| -rw-r--r-- | src/output/SDRDevice.h | 2 | 
3 files changed, 186 insertions, 23 deletions
diff --git a/src/output/Dexter.cpp b/src/output/Dexter.cpp index dd882f2..515d810 100644 --- a/src/output/Dexter.cpp +++ b/src/output/Dexter.cpp @@ -344,30 +344,160 @@ SDRDevice::run_statistics_t Dexter::get_run_statistics(void) const          std::unique_lock<std::mutex> lock(m_attr_thread_mutex);          rs["underruns"] = underflows;      } -    rs["overruns"] = 0; -    rs["late_packets"] = num_late; +    rs["latepackets"] = num_late;      rs["frames"] = num_frames_modulated; -    long long clks = 0; -    int r = 0; -    if ((r = iio_device_attr_read_longlong(m_dexter_dsp_tx, "clks", &clks)) == 0) { -        rs["clks"] = (size_t)clks; +    auto attr_to_stat = [&](const char* attr_name, const char* stat_name) { +        long long attr_value = 0; +        int r = 0; +        if ((r = iio_device_attr_read_longlong(m_dexter_dsp_tx, attr_name, &attr_value)) == 0) { +            rs[stat_name] = (size_t)attr_value; +        } +        else { +            rs[stat_name] = (ssize_t)-1; +            etiLog.level(error) << "Failed to get dexter_dsp_tx." << attr_name << ": " << get_iio_error(r); +        } +    }; + +    attr_to_stat("clks", "clks"); +    attr_to_stat("stream0_fifo_not_empty_clks", "fifo_not_empty_clks"); +    attr_to_stat("gpsdo_locked", "gpsdo_locked"); +    attr_to_stat("pps_clk_error_hz", "pps_clk_error_hz"); +    attr_to_stat("pps_cnt", "pps_cnt"); +    attr_to_stat("dsp_version", "dsp_version"); + +    constexpr double VMINFACT = 0.85; +    constexpr double VMAXFACT = 1.15; +    bool voltage_ok = true; +    bool temp_ok = true; + +    { +        std::ifstream in("/sys/bus/i2c/devices/1-002f/hwmon/hwmon0/in2_input", std::ios::in | std::ios::binary); +        if (in) { +            double vcc3v3; +            in >> vcc3v3; +            rs["vcc3v3"] = vcc3v3 * (18+36)/36.0/1000.0; +            voltage_ok = (vcc3v3 > VMINFACT * 3.3) and (vcc3v3 < VMAXFACT * 3.3); +        } +        else { +            rs["vcc3v3"] = -1; +            voltage_ok = false; +        }      } -    else { -        rs["clks"] = (ssize_t)-1; -        etiLog.level(error) << "Failed to get dexter_dsp_tx.clks: " << get_iio_error(r); +    { +        std::ifstream in("/sys/bus/i2c/devices/1-002f/hwmon/hwmon0/in1_input", std::ios::in | std::ios::binary); +        if (in) { +            double vcc5v4; +            in >> vcc5v4; +            rs["vcc5v4"] = vcc5v4 * (51+36)/36.0/1000.0; +            voltage_ok = (vcc5v4 > VMINFACT * 5.4) and (vcc5v4 < VMAXFACT * 5.4); +        } +        else { +            rs["vcc5v4"] = -1; +            voltage_ok = false; +        } +    } +    { +        std::ifstream in("/sys/bus/i2c/devices/1-002f/hwmon/hwmon0/in3_input", std::ios::in | std::ios::binary); +        if (in) { +            double vfan; +            in >> vfan; +            rs["vfan"] = vfan * (560+22)/22.0/1000.0; +        } +        else { +            rs["vfan"] = -1; +            voltage_ok = false; +        } +    } +    { +        std::ifstream in("/sys/bus/i2c/devices/1-002f/hwmon/hwmon0/in0_input", std::ios::in | std::ios::binary); +        if (in) { +            double vccmainin; +            in >> vccmainin; +            rs["vcc_main_in"] = vccmainin * (560+22)/22.0/1000.0; +            voltage_ok |= vccmainin > 10.0; +        } +        else { +            rs["vcc_main_in"] = -1; +            voltage_ok = false; +        }      } +    { +        std::ifstream in("/sys/bus/i2c/devices/1-002f/hwmon/hwmon0/in4_input", std::ios::in | std::ios::binary); +        if (in) { +            double vcc3v3pll; +            in >> vcc3v3pll; +            rs["vcc3v3pll"] = vcc3v3pll * (18+36)/36.0/1000.0; +            voltage_ok = (vcc3v3pll > VMINFACT * 3.3) and (vcc3v3pll < VMAXFACT * 3.3); +        } +        else { +            rs["vcc3v3pll"] = -1; +            voltage_ok = false; +        } +    } +    { +        std::ifstream in("/sys/bus/i2c/devices/1-002f/hwmon/hwmon0/in5_input", std::ios::in | std::ios::binary); +        if (in) { +            double vcc2v5io; +            in >> vcc2v5io; +            rs["vcc2v5io"] = vcc2v5io * (4.7+36)/36.0/1000.0; +            voltage_ok = (vcc2v5io > VMINFACT * 2.5) and (vcc2v5io < VMAXFACT * 2.5); +        } +        else { +            rs["vcc2v5io"] = -1; +            voltage_ok = false; +        } +    } +    { +        std::ifstream in("/sys/bus/i2c/devices/1-002f/hwmon/hwmon0/in6_input", std::ios::in | std::ios::binary); +        if (in) { +            double vccocxo; +            in >> vccocxo; +            rs["vccocxo"] = vccocxo * (51+36)/36.0/1000.0; +        } +        else { +            rs["vccocxo"] = -1; +            voltage_ok = false; +        } +    } + +    optional<double> tfpga; +    for (int i = 0; i < 100; i++) { +        std::string path = "/sys/bus/iio/devices/iio:device"; +        path += to_string(i); -    long long fifo_not_empty_clks = 0; +        std::ifstream iio_name(path + "/name", std::ios::in | std::ios::binary); +        std::ostringstream sstr; +        sstr << iio_name.rdbuf(); +        if (sstr.str() == "xadc\n") { +            std::ifstream in_scale(path + "/in_temp0_scale", std::ios::in | std::ios::binary); +            std::ifstream in_offset(path + "/in_temp0_offset", std::ios::in | std::ios::binary); +            std::ifstream in_temp0_raw(path + "/in_temp0_raw", std::ios::in | std::ios::binary); -    if ((r = iio_device_attr_read_longlong( -                    m_dexter_dsp_tx, "stream0_fifo_not_empty_clks", &fifo_not_empty_clks)) == 0) { -        rs["fifo_not_empty_clks"] = (size_t)fifo_not_empty_clks; +            if (in_scale and in_offset and in_temp0_raw) { +                double scale, offset, temp0_raw ; +                in_scale >> scale; +                in_offset >> offset; +                in_temp0_raw >> temp0_raw; + +                tfpga = (temp0_raw + offset) * scale / 1000.0; +            } +            break; +        } +    } + +    if (tfpga) { +        rs["tempfpga"] = *tfpga; +        temp_ok |= *tfpga <= 85;      }      else { -        rs["fifo_not_empty_clks"] = (ssize_t)-1; -        etiLog.level(error) << "Failed to get dexter_dsp_tx.fifo_not_empty_clks: " << get_iio_error(r); +        rs["tempfpga"] = -1; +        temp_ok = false;      } + +    rs["voltage_alarm"] = not voltage_ok; +    rs["temp_alarm"] = not temp_ok; +      return rs;  } @@ -408,7 +538,6 @@ size_t Dexter::receive_frame(  bool Dexter::is_clk_source_ok() const  { -    // TODO      return true;  } @@ -419,8 +548,15 @@ const char* Dexter::device_name(void) const  std::optional<double> Dexter::get_temperature(void) const  { -    // TODO XADC contains temperature, but value is weird -    return std::nullopt; +    std::ifstream in("/sys/bus/i2c/devices/1-002f/hwmon/hwmon0/temp1_input", std::ios::in | std::ios::binary); +    if (in) { +        double tbaseboard; +        in >> tbaseboard; +        return tbaseboard / 1000.0; +    } +    else { +        return {}; +    }  }  void Dexter::transmit_frame(struct FrameData&& frame) diff --git a/src/output/SDR.cpp b/src/output/SDR.cpp index 99ced7d..cc080dc 100644 --- a/src/output/SDR.cpp +++ b/src/output/SDR.cpp @@ -25,7 +25,9 @@   */  #include "output/SDR.h" +#include "output/UHD.h"  #include "output/Lime.h" +#include "output/Dexter.h"  #include "PcDebug.h"  #include "Log.h" @@ -82,8 +84,14 @@ SDR::SDR(SDRDeviceConfig& config, std::shared_ptr<SDRDevice> device) :      RC_ADD_PARAMETER(underruns, "Counter of number of underruns");      RC_ADD_PARAMETER(latepackets, "Counter of number of late packets");      RC_ADD_PARAMETER(frames, "Counter of number of frames modulated"); -    RC_ADD_PARAMETER(gpsdo_num_sv, "Number of Satellite Vehicles tracked by GPSDO"); -    RC_ADD_PARAMETER(gpsdo_holdover, "1 if the GPSDO is in holdover, 0 if it is using gnss"); + +#ifdef HAVE_OUTPUT_UHD +    if (std::dynamic_pointer_cast<UHD>(device)) { +        RC_ADD_PARAMETER(gpsdo_num_sv, "Number of Satellite Vehicles tracked by GPSDO"); +        RC_ADD_PARAMETER(gpsdo_holdover, "1 if the GPSDO is in holdover, 0 if it is using gnss"); +    } +#endif // HAVE_OUTPUT_UHD +      RC_ADD_PARAMETER(queued_frames_ms, "Number of frames queued, represented in milliseconds");  #ifdef HAVE_LIMESDR @@ -93,8 +101,24 @@ SDR::SDR(SDRDeviceConfig& config, std::shared_ptr<SDRDevice> device) :  #endif // HAVE_LIMESDR  #ifdef HAVE_DEXTER -    RC_ADD_PARAMETER(clks, "DEXTER internal clk counter value"); -    RC_ADD_PARAMETER(fifo_not_empty_clks, "DEXTER internal clk counter value when FIFO was last empty"); +    if (std::dynamic_pointer_cast<Dexter>(device)) { +        RC_ADD_PARAMETER(clks, "DEXTER internal clk counter value"); +        RC_ADD_PARAMETER(fifo_not_empty_clks, "DEXTER internal clk counter value when FIFO was last empty"); +        RC_ADD_PARAMETER(gpsdo_locked, "1 if GPSDO is locked"); +        RC_ADD_PARAMETER(pps_clk_error_hz, "Estimated error in Hz of clock"); +        RC_ADD_PARAMETER(pps_cnt, "Number of 1PPS pulses seen from GPS"); +        RC_ADD_PARAMETER(dsp_version, "Version of FPGA DSP"); +        RC_ADD_PARAMETER(vcc3v3, "Voltage of VCC 3V3"); +        RC_ADD_PARAMETER(vcc5v4, "Voltage of VCC 5V4"); +        RC_ADD_PARAMETER(vfan, "Fan voltage"); +        RC_ADD_PARAMETER(vcc_main_in, "Main input voltage"); +        RC_ADD_PARAMETER(vcc3v3pll, "Voltage of VCC 3V3 PLL"); +        RC_ADD_PARAMETER(vcc2v5io, "Voltage of VCC 2V5 IO"); +        RC_ADD_PARAMETER(vccocxo, "OCXO voltage"); +        RC_ADD_PARAMETER(tempfpga, "FPGA temperature [celsius]"); +        RC_ADD_PARAMETER(voltage_alarm, "Voltage out of bounds"); +        RC_ADD_PARAMETER(temp_alarm, "Temperature out of bounds"); +    }  #endif // HAVE_DEXTER  } @@ -455,6 +479,9 @@ const string SDR::get_parameter(const string& parameter) const                  if (std::holds_alternative<string>(value)) {                      ss << std::get<string>(value);                  } +                else if (std::holds_alternative<double>(value)) { +                    ss << std::get<double>(value); +                }                  else if (std::holds_alternative<ssize_t>(value)) {                      ss << std::get<ssize_t>(value);                  } diff --git a/src/output/SDRDevice.h b/src/output/SDRDevice.h index 337d501..a4f551c 100644 --- a/src/output/SDRDevice.h +++ b/src/output/SDRDevice.h @@ -112,7 +112,7 @@ struct FrameData {  // All SDR Devices must implement the SDRDevice interface  class SDRDevice {      public: -        using run_statistic_t = std::variant<std::string, size_t, ssize_t, bool>; +        using run_statistic_t = std::variant<std::string, double, size_t, ssize_t, bool>;          using run_statistics_t = std::unordered_map<std::string, run_statistic_t>;          virtual void tune(double lo_offset, double frequency) = 0;  | 
