diff options
Diffstat (limited to 'src/output/Dexter.cpp')
-rw-r--r-- | src/output/Dexter.cpp | 172 |
1 files changed, 154 insertions, 18 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) |