aboutsummaryrefslogtreecommitdiffstats
path: root/src/output
diff options
context:
space:
mode:
Diffstat (limited to 'src/output')
-rw-r--r--src/output/Dexter.cpp172
-rw-r--r--src/output/SDR.cpp35
-rw-r--r--src/output/SDRDevice.h2
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;