diff --git a/Software/PC_Application/Device/device.cpp b/Software/PC_Application/Device/device.cpp index b2fd6b9..7f5d6a8 100644 --- a/Software/PC_Application/Device/device.cpp +++ b/Software/PC_Application/Device/device.cpp @@ -124,6 +124,7 @@ static constexpr Protocol::DeviceInfo defaultInfo = { .source_locked = 0, .LO1_locked = 0, .ADC_overload = 0, + .unlevel = 0, .temp_source = 0, .temp_LO1 = 0, .temp_MCU = 0, diff --git a/Software/PC_Application/Traces/trace.cpp b/Software/PC_Application/Traces/trace.cpp index 9f388de..ddb672b 100644 --- a/Software/PC_Application/Traces/trace.cpp +++ b/Software/PC_Application/Traces/trace.cpp @@ -11,6 +11,7 @@ Trace::Trace(QString name, QColor color, LiveParameter live) _color(color), _liveType(LivedataType::Overwrite), _liveParam(live), + vFactor(0.66), reflection(true), visible(true), paused(false), @@ -103,6 +104,11 @@ void Trace::setName(QString name) { emit nameChanged(); } +void Trace::setVelocityFactor(double v) +{ + vFactor = v; +} + void Trace::fillFromTouchstone(Touchstone &t, unsigned int parameter) { if(parameter >= t.ports()*t.ports()) { @@ -249,8 +255,7 @@ const std::vector& Trace::getMathOperations() const double Trace::velocityFactor() { - // TODO make changeable - return 0.66; + return vFactor; } double Trace::timeToDistance(double time) @@ -293,8 +298,9 @@ nlohmann::json Trace::toJSON() j["filename"] = filename.toStdString(); j["parameter"] = fileParemeter; } + j["velocityFactor"] = vFactor; j["reflection"] = reflection; - // TODO how to save assigned markers? + nlohmann::json mathList; for(auto m : mathOps) { if(m.math->getType() == Type::Last) { @@ -343,6 +349,7 @@ void Trace::fromJSON(nlohmann::json j) throw runtime_error("Failed to create from file:" + what); } } + vFactor = j.value("velocityFactor", 0.66); reflection = j.value("reflection", false); for(auto jm : j["math"]) { QString operation = QString::fromStdString(jm.value("operation", "")); diff --git a/Software/PC_Application/Traces/trace.h b/Software/PC_Application/Traces/trace.h index 6ff3f22..ae95136 100644 --- a/Software/PC_Application/Traces/trace.h +++ b/Software/PC_Application/Traces/trace.h @@ -44,6 +44,7 @@ public: void addData(const Data& d, const Protocol::SweepSettings& s); void addData(const Data& d, const Protocol::SpectrumAnalyzerSettings& s); void setName(QString name); + void setVelocityFactor(double v); void fillFromTouchstone(Touchstone &t, unsigned int parameter); QString fillFromCSV(CSV &csv, unsigned int parameter); // returns the suggested trace name (not yet set in member data) void fromLivedata(LivedataType type, LiveParameter param); @@ -146,6 +147,7 @@ private: QColor _color; LivedataType _liveType; LiveParameter _liveParam; + double vFactor; bool reflection; bool visible; bool paused; diff --git a/Software/PC_Application/Traces/traceeditdialog.cpp b/Software/PC_Application/Traces/traceeditdialog.cpp index 40e81a3..c504f9d 100644 --- a/Software/PC_Application/Traces/traceeditdialog.cpp +++ b/Software/PC_Application/Traces/traceeditdialog.cpp @@ -10,8 +10,10 @@ TraceEditDialog::TraceEditDialog(Trace &t, QWidget *parent) : trace(t) { ui->setupUi(this); + ui->vFactor->setPrecision(3); ui->name->setText(t.name()); ui->color->setColor(trace.color()); + ui->vFactor->setValue(t.velocityFactor()); connect(ui->color, &ColorPickerButton::colorChanged, [=](const QColor& color){ trace.setColor(color); }); @@ -109,6 +111,7 @@ TraceEditDialog::~TraceEditDialog() void TraceEditDialog::on_buttonBox_accepted() { trace.setName(ui->name->text()); + trace.setVelocityFactor(ui->vFactor->value()); if(!trace.isCalibration()) { // only apply changes if it is not a calibration trace if (ui->bFile->isChecked()) { diff --git a/Software/PC_Application/Traces/traceeditdialog.ui b/Software/PC_Application/Traces/traceeditdialog.ui index 6a3f4bb..a368c18 100644 --- a/Software/PC_Application/Traces/traceeditdialog.ui +++ b/Software/PC_Application/Traces/traceeditdialog.ui @@ -10,7 +10,7 @@ 0 0 282 - 355 + 365 @@ -63,6 +63,16 @@ + + + + Velocity Factor: + + + + + + @@ -181,6 +191,11 @@ QPushButton
CustomWidgets/colorpickerbutton.h
+ + SIUnitEdit + QLineEdit +
CustomWidgets/siunitedit.h
+
diff --git a/Software/PC_Application/VNA/Deembedding/twothru.cpp b/Software/PC_Application/VNA/Deembedding/twothru.cpp index 08143b2..f53ac5f 100644 --- a/Software/PC_Application/VNA/Deembedding/twothru.cpp +++ b/Software/PC_Application/VNA/Deembedding/twothru.cpp @@ -75,7 +75,7 @@ void TwoThru::updateGUI() +Unit::ToString(measurements2xthru.front().frequency, "Hz", " kMG", 4)+" to " +Unit::ToString(measurements2xthru.back().frequency, "Hz", " kMG", 4)); } else { - ui->l2xthru->setText("Not available, not de-embedding"); + ui->l2xthru->setText("Not available"); } if(measurementsDUT.size() > 0) { @@ -83,7 +83,7 @@ void TwoThru::updateGUI() +Unit::ToString(measurementsDUT.front().frequency, "Hz", " kMG", 4)+" to " +Unit::ToString(measurementsDUT.back().frequency, "Hz", " kMG", 4)); } else { - ui->lDUT->setText("Not available, not de-embedding"); + ui->lDUT->setText("Not available"); } if(points.size() > 0) { @@ -91,7 +91,7 @@ void TwoThru::updateGUI() +Unit::ToString(points.front().freq, "Hz", " kMG", 4)+" to " +Unit::ToString(points.back().freq, "Hz", " kMG", 4)); } else { - ui->lPoints->setText("Not available, not de-embedding"); + ui->lPoints->setText("No values calculated, not de-embedding"); } if (measurementsDUT.size() > 0 && measurements2xthru.size() > 0) { diff --git a/Software/PC_Application/appwindow.cpp b/Software/PC_Application/appwindow.cpp index 3dc0dfa..5cf5755 100644 --- a/Software/PC_Application/appwindow.cpp +++ b/Software/PC_Application/appwindow.cpp @@ -72,6 +72,21 @@ AppWindow::AppWindow(QWidget *parent) ui->statusbar->addWidget(div1); ui->statusbar->addWidget(&lDeviceInfo); ui->statusbar->addWidget(new QLabel, 1); + + lADCOverload.setStyleSheet("color : red"); + lADCOverload.setText("ADC overload"); + lADCOverload.setVisible(false); + ui->statusbar->addWidget(&lADCOverload); + + lUnlevel.setStyleSheet("color : red"); + lUnlevel.setText("Unlevel"); + lUnlevel.setVisible(false); + ui->statusbar->addWidget(&lUnlevel); + + lUnlock.setStyleSheet("color : red"); + lUnlock.setText("Unlock"); + lUnlock.setVisible(false); + ui->statusbar->addWidget(&lUnlock); //ui->statusbar->setStyleSheet("QStatusBar::item { border: 1px solid black; };"); CreateToolbars(); @@ -219,6 +234,9 @@ void AppWindow::ConnectToDevice(QString serial) connect(device, &Device::ConnectionLost, this, &AppWindow::DeviceConnectionLost); connect(device, &Device::DeviceInfoUpdated, [this]() { lDeviceInfo.setText(device->getLastDeviceInfoString()); + lADCOverload.setVisible(device->Info().ADC_overload); + lUnlevel.setVisible(device->Info().unlevel); + lUnlock.setVisible(!device->Info().LO1_locked || !device->Info().source_locked); }); connect(device, &Device::NeedsFirmwareUpdate, this, &AppWindow::DeviceNeedsUpdate); ui->actionDisconnect->setEnabled(true); diff --git a/Software/PC_Application/appwindow.h b/Software/PC_Application/appwindow.h index aaa96bb..425a97b 100644 --- a/Software/PC_Application/appwindow.h +++ b/Software/PC_Application/appwindow.h @@ -78,6 +78,10 @@ private: // Status bar widgets QLabel lConnectionStatus; QLabel lDeviceInfo; + // Error flag labels + QLabel lADCOverload; + QLabel lUnlevel; + QLabel lUnlock; Ui::MainWindow *ui; }; diff --git a/Software/VNA_embedded/.cproject b/Software/VNA_embedded/.cproject index 7343c51..c8b0b2e 100644 --- a/Software/VNA_embedded/.cproject +++ b/Software/VNA_embedded/.cproject @@ -29,7 +29,7 @@ - + diff --git a/Software/VNA_embedded/Application/Communication/Protocol.cpp b/Software/VNA_embedded/Application/Communication/Protocol.cpp index 34bac21..0b4a90f 100644 --- a/Software/VNA_embedded/Application/Communication/Protocol.cpp +++ b/Software/VNA_embedded/Application/Communication/Protocol.cpp @@ -252,6 +252,7 @@ static Protocol::DeviceInfo DecodeDeviceInfo(uint8_t *buf) { d.source_locked = e.getBits(1); d.LO1_locked = e.getBits(1); d.ADC_overload = e.getBits(1); + d.unlevel = e.getBits(1); e.get(d.temp_source); e.get(d.temp_LO1); e.get(d.temp_MCU); @@ -283,6 +284,7 @@ static int16_t EncodeDeviceInfo(Protocol::DeviceInfo d, uint8_t *buf, e.addBits(d.source_locked, 1); e.addBits(d.LO1_locked, 1); e.addBits(d.ADC_overload, 1); + e.addBits(d.unlevel, 1); e.add(d.temp_source); e.add(d.temp_LO1); e.add(d.temp_MCU); diff --git a/Software/VNA_embedded/Application/Communication/Protocol.hpp b/Software/VNA_embedded/Application/Communication/Protocol.hpp index a4b98d4..f97e779 100644 --- a/Software/VNA_embedded/Application/Communication/Protocol.hpp +++ b/Software/VNA_embedded/Application/Communication/Protocol.hpp @@ -53,6 +53,7 @@ using DeviceInfo = struct _deviceInfo { uint8_t source_locked:1; uint8_t LO1_locked:1; uint8_t ADC_overload:1; + uint8_t unlevel:1; uint8_t temp_source; uint8_t temp_LO1; uint8_t temp_MCU; diff --git a/Software/VNA_embedded/Application/Generator.cpp b/Software/VNA_embedded/Application/Generator.cpp index 1df2845..6a127af 100644 --- a/Software/VNA_embedded/Application/Generator.cpp +++ b/Software/VNA_embedded/Application/Generator.cpp @@ -44,6 +44,7 @@ void Generator::Setup(Protocol::GeneratorSettings g) { } } auto amplitude = HW::GetAmplitudeSettings(g.cdbm_level, g.frequency, g.applyAmplitudeCorrection, g.activePort == 2); + HW::SetOutputUnlevel(amplitude.unlevel); // Select correct source if(g.frequency < HW::BandSwitchFrequency) { m.SourceLowEN = 1; diff --git a/Software/VNA_embedded/Application/Hardware.cpp b/Software/VNA_embedded/Application/Hardware.cpp index 116527f..3b8a83a 100644 --- a/Software/VNA_embedded/Application/Hardware.cpp +++ b/Software/VNA_embedded/Application/Hardware.cpp @@ -16,6 +16,7 @@ static uint32_t extOutFreq = 0; static bool extRefInUse = false; HW::Mode activeMode; +static bool unlevel = false; static Protocol::ReferenceSettings ref; static uint32_t lastISR; @@ -186,6 +187,7 @@ void HW::SetMode(Mode mode) { // already the correct mode return; } + unlevel = false; switch(activeMode) { case Mode::Manual: Manual::Stop(); @@ -215,6 +217,7 @@ bool HW::GetTemps(uint8_t *source, uint8_t *lo) { } void HW::SetIdle() { + unlevel = false; FPGA::AbortSweep(); FPGA::SetMode(FPGA::Mode::FPGA); FPGA::Enable(FPGA::Periphery::SourceChip, false); @@ -283,6 +286,10 @@ bool HW::TimedOut() { } } +void HW::SetOutputUnlevel(bool unlev) { + unlevel = unlev; +} + void HW::fillDeviceInfo(Protocol::DeviceInfo *info, bool updateEvenWhenBusy) { // copy constant default values memcpy(info, &HW::Info, sizeof(HW::Info)); @@ -311,6 +318,7 @@ void HW::fillDeviceInfo(Protocol::DeviceInfo *info, bool updateEvenWhenBusy) { info->source_locked = (status & (int) FPGA::Interrupt::SourceUnlock) ? 0 : 1; info->extRefAvailable = Ref::available(); info->extRefInUse = extRefInUse; + info->unlevel = unlevel; info->temp_LO1 = tempLO; info->temp_source = tempSource; FPGA::ResetADCLimits(); diff --git a/Software/VNA_embedded/Application/Hardware.hpp b/Software/VNA_embedded/Application/Hardware.hpp index e4bd642..370505f 100644 --- a/Software/VNA_embedded/Application/Hardware.hpp +++ b/Software/VNA_embedded/Application/Hardware.hpp @@ -60,6 +60,7 @@ static constexpr Protocol::DeviceInfo Info = { .source_locked = 0, .LO1_locked = 0, .ADC_overload = 0, + .unlevel = 0, .temp_source = 0, .temp_LO1 = 0, .temp_MCU = 0, @@ -89,6 +90,8 @@ void SetIdle(); void Work(); bool TimedOut(); +void SetOutputUnlevel(bool unlev); + using AmplitudeSettings = struct _amplitudeSettings { uint8_t attenuator; union { diff --git a/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp b/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp index 478b31b..2cc7007 100644 --- a/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp +++ b/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp @@ -64,6 +64,10 @@ static void StartNextSample() { if(trackingFreq > 0 && trackingFreq <= (int64_t) HW::Info.limits_maxFreq) { // tracking frequency is valid, calculate required settings and select band auto amplitude = HW::GetAmplitudeSettings(s.trackingPower, trackingFreq, s.applySourceCorrection, s.trackingGeneratorPort); + // only set the flag here, it is reset at the beginning of each sweep (this makes sure it is set if any of the points are not reached by the TG) + if(amplitude.unlevel) { + HW::SetOutputUnlevel(true); + } attenuator = amplitude.attenuator; if(trackingFreq < HW::BandSwitchFrequency) { Si5351.SetCLK(SiChannel::LowbandSource, trackingFreq, Si5351C::PLL::B, amplitude.lowBandPower); @@ -161,6 +165,7 @@ static void StartNextSample() { void SA::Setup(Protocol::SpectrumAnalyzerSettings settings) { LOG_DEBUG("Setting up..."); + HW::SetOutputUnlevel(false); SA::Stop(); vTaskDelay(5); s = settings; @@ -369,11 +374,9 @@ void SA::Work() { } // setup for next step signalIDstep = 0; - if(pointCnt < points - DFTpoints) { - pointCnt += DFTpoints; - } else { - pointCnt = 0; - // sweep finished, extract device info + + if(pointCnt % 10 == 0) { + // send device info every nth point FPGA::Enable(FPGA::Periphery::SourceChip); // needs to enable the chip to get a valid temperature reading Protocol::PacketInfo packet; packet.type = Protocol::PacketType::DeviceInfo; @@ -381,6 +384,14 @@ void SA::Work() { FPGA::Disable(FPGA::Periphery::SourceChip); Communication::Send(packet); } + + if(pointCnt < points - DFTpoints) { + pointCnt += DFTpoints; + } else { + pointCnt = 0; + // reset possibly active unlevel flag before next sweep + HW::SetOutputUnlevel(false); + } } else { // more measurements required for signal ID signalIDstep++;