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