From 047f6ce98173f529eb51c3a4f88adb47edf3c048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20K=C3=A4berich?= Date: Sat, 6 Aug 2022 16:22:12 +0200 Subject: [PATCH] more flexible USB protocol for VNA settings/measurements --- Software/PC_Application/Device/device.cpp | 4 +- Software/PC_Application/Device/device.h | 2 +- .../PC_Application/Device/virtualdevice.cpp | 44 ++++-- .../PC_Application/Device/virtualdevice.h | 7 +- Software/PC_Application/Traces/tracemodel.cpp | 1 + Software/PC_Application/VNA/vna.cpp | 4 +- .../Application/Communication/Protocol.cpp | 23 ++- .../Application/Communication/Protocol.hpp | 135 ++++++++++++++++-- .../Application/Drivers/FPGA/FPGA.cpp | 4 +- .../Application/Drivers/FPGA/FPGA.hpp | 2 +- .../Application/Drivers/USB/usb.c | 2 +- .../Application/SpectrumAnalyzer.cpp | 2 +- Software/VNA_embedded/Application/VNA.cpp | 55 ++----- 13 files changed, 203 insertions(+), 82 deletions(-) diff --git a/Software/PC_Application/Device/device.cpp b/Software/PC_Application/Device/device.cpp index 570e535..b3fbc3c 100644 --- a/Software/PC_Application/Device/device.cpp +++ b/Software/PC_Application/Device/device.cpp @@ -463,8 +463,8 @@ void Device::ReceivedData() handled_len = Protocol::DecodeBuffer(dataBuffer->getBuffer(), dataBuffer->getReceived(), &packet); dataBuffer->removeBytes(handled_len); switch(packet.type) { - case Protocol::PacketType::Datapoint: - emit DatapointReceived(packet.datapoint); + case Protocol::PacketType::VNADatapoint: + emit DatapointReceived(packet.VNAdatapoint); break; case Protocol::PacketType::ManualStatusV1: emit ManualStatusReceived(packet.manualStatusV1); diff --git a/Software/PC_Application/Device/device.h b/Software/PC_Application/Device/device.h index b1295a3..874c217 100644 --- a/Software/PC_Application/Device/device.h +++ b/Software/PC_Application/Device/device.h @@ -77,7 +77,7 @@ public: // Returns serial numbers of all connected devices static std::set GetDevices(); signals: - void DatapointReceived(Protocol::Datapoint); + void DatapointReceived(Protocol::VNADatapoint<32>*); void ManualStatusReceived(Protocol::ManualStatusV1); void SpectrumResultReceived(Protocol::SpectrumAnalyzerResult); void AmplitudeCorrectionPointReceived(Protocol::AmplitudeCorrectionPoint); diff --git a/Software/PC_Application/Device/virtualdevice.cpp b/Software/PC_Application/Device/virtualdevice.cpp index acbae2b..8bdca9e 100644 --- a/Software/PC_Application/Device/virtualdevice.cpp +++ b/Software/PC_Application/Device/virtualdevice.cpp @@ -3,6 +3,8 @@ #include "preferences.h" #include "../VNA_embedded/Application/Communication/Protocol.hpp" +#include + static VirtualDevice *connected = nullptr; using namespace std; @@ -193,20 +195,30 @@ VirtualDevice::VirtualDevice(QString serial) m.measurements["PORT2"] = res.port2; emit SAmeasurementReceived(m); }); - connect(dev, &Device::DatapointReceived, [&](Protocol::Datapoint res){ + connect(dev, &Device::DatapointReceived, [&](Protocol::VNADatapoint<32> *res){ VNAMeasurement m; - m.pointNum = res.pointNum; + m.pointNum = res->pointNum; m.Z0 = 50.0; if(zerospan) { - m.us = res.us; + m.us = res->us; } else { - m.frequency = res.frequency; - m.dBm = (double) res.cdbm / 100; + m.frequency = res->frequency; + m.dBm = (double) res->cdBm / 100; } - m.measurements["S11"] = complex(res.real_S11, res.imag_S11); - m.measurements["S21"] = complex(res.real_S21, res.imag_S21); - m.measurements["S12"] = complex(res.real_S12, res.imag_S12); - m.measurements["S22"] = complex(res.real_S22, res.imag_S22); + for(auto map : portStageMapping) { + // map.first is the port (starts at zero) + // map.second is the stage at which this port had the stimulus (starts at zero) + complex ref = res->getValue(map.second, map.first, true); + for(int i=0;i<2;i++) { + complex input = res->getValue(map.second, i, false); + if(!std::isnan(ref.real()) && !std::isnan(input.real())) { + // got both required measurements + QString name = "S"+QString::number(i+1)+QString::number(map.first+1); + m.measurements[name] = input / ref; + } + } + } + delete res; emit VNAmeasurementReceived(m); }); } else { @@ -301,6 +313,13 @@ bool VirtualDevice::setVNA(const VirtualDevice::VNASettings &s, std::functionstage mapping + portStageMapping.clear(); + for(int i=0;iConfigure(sd, [=](Device::TransmissionResult r){ if(cb) { cb(r == Device::TransmissionResult::Ack); @@ -372,6 +393,7 @@ bool VirtualDevice::setSA(const VirtualDevice::SASettings &s, std::functionConfigure(sd, [=](Device::TransmissionResult r){ if(cb) { cb(r == Device::TransmissionResult::Ack); diff --git a/Software/PC_Application/Device/virtualdevice.h b/Software/PC_Application/Device/virtualdevice.h index c8c3513..9a8d1d7 100644 --- a/Software/PC_Application/Device/virtualdevice.h +++ b/Software/PC_Application/Device/virtualdevice.h @@ -67,7 +67,7 @@ public: double IFBW; int points; bool logSweep; - std::vector excitedPorts; + std::vector excitedPorts; // port count starts at one }; class VNAMeasurement { public: @@ -177,12 +177,15 @@ private: Status status; bool isCompound; std::vector devices; - std::vector portMapping; bool zerospan; std::map results; CompoundDevice *cdev; + + std::map*>> compoundDataBuffer; + + std::map portStageMapping; // maps from excitedPort (count starts at zero) to stage (count starts at zero) }; Q_DECLARE_METATYPE(VirtualDevice::Status) diff --git a/Software/PC_Application/Traces/tracemodel.cpp b/Software/PC_Application/Traces/tracemodel.cpp index 32ce4c6..13f87c7 100644 --- a/Software/PC_Application/Traces/tracemodel.cpp +++ b/Software/PC_Application/Traces/tracemodel.cpp @@ -157,6 +157,7 @@ std::vector TraceModel::getTraces() const bool TraceModel::PortExcitationRequired(int port) { + port++; for(auto t : traces) { if(t->getSource() == Trace::Source::Live && !t->isPaused()) { // this trace needs measurements from VNA, check if port has to be excited for its measurement diff --git a/Software/PC_Application/VNA/vna.cpp b/Software/PC_Application/VNA/vna.cpp index 2464fb7..b88642d 100644 --- a/Software/PC_Application/VNA/vna.cpp +++ b/Software/PC_Application/VNA/vna.cpp @@ -925,11 +925,11 @@ void VNA::SettingsChanged(bool resetTraces, std::function cb) VirtualDevice::VNASettings s = {}; s.IFBW = settings.bandwidth; if(Preferences::getInstance().Acquisition.alwaysExciteBothPorts) { - for(int i=1;i<=VirtualDevice::getInfo(window->getDevice()).ports;i++) { + for(int i=0;igetDevice()).ports;i++) { s.excitedPorts.push_back(i); } } else { - for(int i=1;i<=VirtualDevice::getInfo(window->getDevice()).ports;i++) { + for(int i=0;igetDevice()).ports;i++) { if(traceModel.PortExcitationRequired(i)) s.excitedPorts.push_back(i); } diff --git a/Software/VNA_embedded/Application/Communication/Protocol.cpp b/Software/VNA_embedded/Application/Communication/Protocol.cpp index b79c5be..7d94264 100644 --- a/Software/VNA_embedded/Application/Communication/Protocol.cpp +++ b/Software/VNA_embedded/Application/Communication/Protocol.cpp @@ -62,7 +62,7 @@ uint16_t Protocol::DecodeBuffer(uint8_t *buf, uint16_t len, PacketInfo *info) { /* The complete frame has been received, check checksum */ auto type = (PacketType) data[3]; uint32_t crc = *(uint32_t*) &data[length - 4]; - if(type != PacketType::Datapoint) { + if(type != PacketType::VNADatapoint) { uint32_t compare = CRC32(0, data, length - 4); if(crc != compare) { // CRC mismatch, remove header @@ -70,6 +70,8 @@ uint16_t Protocol::DecodeBuffer(uint8_t *buf, uint16_t len, PacketInfo *info) { info->type = PacketType::None; return data - buf; } + // Valid packet, copy packet type and payload + memcpy(info, &data[3], length - 7); } else { // Datapoint has the CRC set to zero if(crc != 0x00000000) { @@ -77,17 +79,19 @@ uint16_t Protocol::DecodeBuffer(uint8_t *buf, uint16_t len, PacketInfo *info) { info->type = PacketType::None; return data - buf; } + // Create the datapoint + info->type = (PacketType) data[3]; + info->VNAdatapoint = new VNADatapoint<32>; + info->VNAdatapoint->decode(&data[4], length - 8); } - // Valid packet, copy packet type and payload - memcpy(info, &data[3], length - 7); return data - buf + length; } uint16_t Protocol::EncodePacket(const PacketInfo &packet, uint8_t *dest, uint16_t destsize) { int16_t payload_size = 0; switch (packet.type) { - case PacketType::Datapoint: payload_size = sizeof(packet.datapoint); break; +// case PacketType::Datapoint: payload_size = sizeof(packet.datapoint); break; case PacketType::SweepSettings: payload_size = sizeof(packet.settings); break; case PacketType::Reference: payload_size = sizeof(packet.reference); break; case PacketType::DeviceInfo: payload_size = sizeof(packet.info); break; @@ -115,6 +119,7 @@ uint16_t Protocol::EncodePacket(const PacketInfo &packet, uint8_t *dest, uint16_ case PacketType::RequestDeviceStatus: // no payload break; + case PacketType::VNADatapoint: payload_size = packet.VNAdatapoint->requiredBufferSize(); break; case PacketType::None: break; } @@ -126,14 +131,18 @@ uint16_t Protocol::EncodePacket(const PacketInfo &packet, uint8_t *dest, uint16_ dest[0] = header; uint16_t overall_size = payload_size + 8; memcpy(&dest[1], &overall_size, 2); - memcpy(&dest[3], &packet, payload_size + 1); // one additional byte for the packet type - // Calculate checksum + // Further encoding uses a special case for VNADatapoint packettype uint32_t crc = 0x00000000; - if(packet.type == PacketType::Datapoint) { + if(packet.type == PacketType::VNADatapoint) { // CRC calculation takes about 18us which is the bulk of the time required to encode and transmit a datapoint. // Skip CRC for data points to optimize throughput + dest[3] = (uint8_t) packet.type; + packet.VNAdatapoint->encode(&dest[4], destsize - 8); crc = 0x00000000; } else { + // Copy rest of the packet + memcpy(&dest[3], &packet, payload_size + 1); // one additional byte for the packet type + // Calculate the CRC crc = CRC32(0, dest, overall_size - 4); } memcpy(&dest[overall_size - 4], &crc, 4); diff --git a/Software/VNA_embedded/Application/Communication/Protocol.hpp b/Software/VNA_embedded/Application/Communication/Protocol.hpp index 424a70c..2593aa8 100644 --- a/Software/VNA_embedded/Application/Communication/Protocol.hpp +++ b/Software/VNA_embedded/Application/Communication/Protocol.hpp @@ -1,13 +1,110 @@ #pragma once #include +#include +#include +#include namespace Protocol { -static constexpr uint16_t Version = 11; +static constexpr uint16_t Version = 12; #pragma pack(push, 1) +enum class Source : uint8_t { + Port1 = 0x01, + Port2 = 0x02, + Port3 = 0x04, + Port4 = 0x08, + Reference = 0x10, +}; + +template class VNADatapoint { +public: + VNADatapoint() { + clear(); + } + + void clear() { + num_values = 0; + pointNum = 0; + cdBm = 0; + frequency = 0; + } + bool addValue(float real, float imag, uint8_t stage, int sourceMask) { + if(num_values >= s) { + return false; + } + real_values[num_values] = real; + imag_values[num_values] = imag; + descr_values[num_values] = stage << 5 | sourceMask; + num_values++; + return true; + } + + bool encode(uint8_t *dest, uint16_t destSize) { + if(requiredBufferSize() > destSize) { + return false; + } + memcpy(dest, &frequency, 8); + memcpy(dest+8, &cdBm, 2); + memcpy(dest+10, &pointNum, 2); + dest += 12; + memcpy(dest, real_values, num_values * 4); + dest += num_values * 4; + memcpy(dest, imag_values, num_values * 4); + dest += num_values * 4; + memcpy(dest, descr_values, num_values); + return true; + } + void decode(const uint8_t *buffer, uint16_t size) { + num_values = (size - (8+2+2)) / (1+4+4); + memcpy(&frequency, buffer, 8); + memcpy(&cdBm, buffer+8, 2); + memcpy(&pointNum, buffer+10, 2); + buffer += 12; + memcpy(real_values, buffer, num_values * 4); + buffer += num_values * 4; + memcpy(imag_values, buffer, num_values * 4); + buffer += num_values * 4; + memcpy(descr_values, buffer, num_values); + } + + std::complex getValue(uint8_t stage, uint8_t port, bool reference) { + uint8_t sourceMask = 0; + sourceMask |= 0x01 << port; + if(reference) { + sourceMask |= (int) Source::Reference; + } + for(int i=0;i> 5 != stage) { + continue; + } + if((descr_values[i] & sourceMask) != sourceMask) { + continue; + } + return std::complex(real_values[i], imag_values[i]); + } + return std::numeric_limits>::quiet_NaN(); + } + + uint16_t requiredBufferSize() { + return 8+2+2+ num_values * (4+4+1); + } + + union { + uint64_t frequency; + uint64_t us; + }; + int16_t cdBm; + uint16_t pointNum; +private: + float real_values[s]; + float imag_values[s]; + uint8_t descr_values[s]; + uint8_t num_values; +}; + using Datapoint = struct _datapoint { float real_S11, imag_S11; float real_S21, imag_S21; @@ -33,11 +130,20 @@ using SweepSettings = struct _sweepSettings { uint16_t points; uint32_t if_bandwidth; int16_t cdbm_excitation_start; // in 1/100 dbm - uint8_t excitePort1:1; - uint8_t excitePort2:1; - uint8_t suppressPeaks:1; - uint8_t fixedPowerSetting:1; // if set the attenuator and source PLL power will not be changed across the sweep - uint8_t logSweep:1; + uint16_t unused:2; + uint16_t suppressPeaks:1; + uint16_t fixedPowerSetting:1; // if set the attenuator and source PLL power will not be changed across the sweep + uint16_t logSweep:1; + uint16_t stages:3; + uint16_t port1Stage:3; + uint16_t port2Stage:3; + /* + * 0: no synchronization + * 1: USB synchronization + * 2: External reference synchronization + * 3: Trigger synchronization (not supported yet by hardware) + */ + uint16_t syncMode:2; int16_t cdbm_excitation_stop; // in 1/100 dbm }; @@ -145,6 +251,13 @@ using SpectrumAnalyzerSettings = struct _spectrumAnalyzerSettings { uint8_t trackingGenerator :1; uint8_t applySourceCorrection :1; uint8_t trackingGeneratorPort :1; // 0 for port1, 1 for port2 + /* + * 0: no synchronization + * 1: USB synchronization + * 2: External reference synchronization + * 3: Trigger synchronization (not supported yet by hardware) + */ + uint8_t syncMode :2; int64_t trackingGeneratorOffset; int16_t trackingPower; }; @@ -191,7 +304,7 @@ using AcquisitionFrequencySettings = struct _acquisitionfrequencysettigns { enum class PacketType : uint8_t { None = 0, - Datapoint = 1, + //Datapoint = 1, // Deprecated, replaced by VNADatapoint SweepSettings = 2, ManualStatusV1 = 3, ManualControlV1 = 4, @@ -217,12 +330,13 @@ enum class PacketType : uint8_t { AcquisitionFrequencySettings = 24, DeviceStatusV1 = 25, RequestDeviceStatus = 26, + VNADatapoint = 27, }; using PacketInfo = struct _packetinfo { PacketType type; union { - Datapoint datapoint; +// Datapoint datapoint; // Deprecated, use VNADatapoint instead SweepSettings settings; ReferenceSettings reference; GeneratorSettings generator; @@ -236,6 +350,11 @@ using PacketInfo = struct _packetinfo { AmplitudeCorrectionPoint amplitudePoint; FrequencyCorrection frequencyCorrection; AcquisitionFrequencySettings acquisitionFrequencySettings; + /* + * When encoding: Pointer may go invalid after call to EncodePacket + * When decoding: VNADatapoint is created on heap by DecodeBuffer, freeing is up to the caller + */ + VNADatapoint<32> *VNAdatapoint; }; }; diff --git a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp index 5083b63..3f184fe 100644 --- a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp +++ b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp @@ -130,10 +130,10 @@ void FPGA::SetSamplesPerPoint(uint32_t nsamples) { WriteRegister(Reg::SamplesPerPoint, nsamples); } -void FPGA::SetupSweep(uint8_t stages, uint8_t port1_stage, uint8_t port2_stage, bool individual_halt) { +void FPGA::SetupSweep(uint8_t stages, uint8_t port1_stage, uint8_t port2_stage, bool synchronize) { uint16_t value = 0x0000; value |= (uint16_t) (stages & 0x07) << 13; - if(individual_halt) { + if(synchronize) { value |= 0x1000; } value |= (port1_stage & 0x07) << 3; diff --git a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp index 88da655..80487dc 100644 --- a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp +++ b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp @@ -114,7 +114,7 @@ bool Init(HaltedCallback cb = nullptr); void WriteRegister(FPGA::Reg reg, uint16_t value); void SetNumberOfPoints(uint16_t npoints); void SetSamplesPerPoint(uint32_t nsamples); -void SetupSweep(uint8_t stages, uint8_t port1_stage, uint8_t port2_stage, bool individual_halt = false); +void SetupSweep(uint8_t stages, uint8_t port1_stage, uint8_t port2_stage, bool synchronize = false); void Enable(Periphery p, bool enable = true); void Disable(Periphery p); bool IsEnabled(Periphery p); diff --git a/Software/VNA_embedded/Application/Drivers/USB/usb.c b/Software/VNA_embedded/Application/Drivers/USB/usb.c index aab7c0a..165d677 100644 --- a/Software/VNA_embedded/Application/Drivers/USB/usb.c +++ b/Software/VNA_embedded/Application/Drivers/USB/usb.c @@ -19,7 +19,7 @@ static uint8_t *USBD_Class_GetDeviceQualifierDescriptor (uint16_t *length); static usbd_recv_callback_t cb; static uint8_t usb_receive_buffer[1024]; -static uint8_t usb_transmit_fifo[8192]; +static uint8_t usb_transmit_fifo[6144]; static uint16_t usb_transmit_read_index = 0; static uint16_t usb_transmit_fifo_level = 0; static bool data_transmission_active = false; diff --git a/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp b/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp index d125da0..a1e8810 100644 --- a/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp +++ b/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp @@ -224,7 +224,7 @@ void SA::Setup(Protocol::SpectrumAnalyzerSettings settings) { FPGA::SetWindow((FPGA::Window) s.WindowType); FPGA::Enable(FPGA::Periphery::LO1Chip); FPGA::Enable(FPGA::Periphery::LO1RF); - FPGA::SetupSweep(0, s.trackingGeneratorPort == 1, s.trackingGeneratorPort == 0); + FPGA::SetupSweep(0, s.trackingGeneratorPort == 1, s.trackingGeneratorPort == 0, s.syncMode != 0); FPGA::Enable(FPGA::Periphery::PortSwitch, s.trackingGenerator); FPGA::Enable(FPGA::Periphery::Amplifier, s.trackingGenerator); FPGA::Enable(FPGA::Periphery::Port1Mixer); diff --git a/Software/VNA_embedded/Application/VNA.cpp b/Software/VNA_embedded/Application/VNA.cpp index e8059a9..d975a7e 100644 --- a/Software/VNA_embedded/Application/VNA.cpp +++ b/Software/VNA_embedded/Application/VNA.cpp @@ -22,9 +22,8 @@ static Protocol::SweepSettings settings; static uint16_t pointCnt; static uint8_t stageCnt; -static uint8_t stages; static double logMultiplier, logFrequency; -static Protocol::Datapoint data; +static Protocol::VNADatapoint<32> data; static bool active = false; static Si5351C::DriveStrength fixedPowerLowband; static bool adcShifted; @@ -81,12 +80,6 @@ bool VNA::Setup(Protocol::SweepSettings s) { VNA::Stop(); vTaskDelay(5); HW::SetMode(HW::Mode::VNA); - if(s.excitePort1 == 0 && s.excitePort2 == 0) { - // both ports disabled, nothing to do - HW::SetIdle(); - active = false; - return false; - } // Abort possible active sweep first FPGA::SetMode(FPGA::Mode::FPGA); FPGA::WriteRegister(FPGA::Reg::ADCPrescaler, HW::getADCPrescaler()); @@ -285,19 +278,7 @@ bool VNA::Setup(Protocol::SweepSettings s) { FPGA::Enable(FPGA::Periphery::SourceRF); FPGA::Enable(FPGA::Periphery::LO1Chip); FPGA::Enable(FPGA::Periphery::LO1RF); - if(s.excitePort1 && s.excitePort2) { - // two stages, port 1 first, followed by port 2 - FPGA::SetupSweep(1, 0, 1); - stages = 2; - } else if(s.excitePort1) { - // one stage, port 1 only - FPGA::SetupSweep(0, 0, 1); - stages = 1; - } else { - // one stage, port 2 only - FPGA::SetupSweep(0, 1, 0); - stages = 1; - } + FPGA::SetupSweep(s.stages, s.port1Stage, s.port2Stage, s.syncMode != 0); FPGA::Enable(FPGA::Periphery::PortSwitch); pointCnt = 0; stageCnt = 0; @@ -315,9 +296,10 @@ bool VNA::Setup(Protocol::SweepSettings s) { static void PassOnData() { Protocol::PacketInfo info; - info.type = Protocol::PacketType::Datapoint; - info.datapoint = data; + info.type = Protocol::PacketType::VNADatapoint; + info.VNAdatapoint = &data; Communication::Send(info); + data.clear(); } bool VNA::MeasurementDone(const FPGA::SamplingResult &result) { @@ -330,11 +312,9 @@ bool VNA::MeasurementDone(const FPGA::SamplingResult &result) { return false; } // normal sweep mode - auto port1_raw = std::complex(result.P1I, result.P1Q); - auto port2_raw = std::complex(result.P2I, result.P2Q); - auto ref = std::complex(result.RefI, result.RefQ); - auto port1 = port1_raw / ref; - auto port2 = port2_raw / ref; + data.addValue(result.P1I, result.P1Q, stageCnt, (int) Protocol::Source::Port1); + data.addValue(result.P2I, result.P2Q, stageCnt, (int) Protocol::Source::Port2); + data.addValue(result.RefI, result.RefQ, stageCnt, (int) Protocol::Source::Port1 | (int) Protocol::Source::Port2 | (int) Protocol::Source::Reference); data.pointNum = pointCnt; if(zerospan) { uint64_t timestamp = HW::getLastISRTimestamp(); @@ -348,24 +328,11 @@ bool VNA::MeasurementDone(const FPGA::SamplingResult &result) { } else { // non-zero span, set frequency/power data.frequency = getPointFrequency(pointCnt); - data.cdbm = settings.cdbm_excitation_start + (settings.cdbm_excitation_stop - settings.cdbm_excitation_start) * pointCnt / (settings.points - 1); - } - if(stageCnt == 0 && settings.excitePort1) { - // stimulus is present at port 1 - data.real_S11 = port1.real(); - data.imag_S11 = port1.imag(); - data.real_S21 = port2.real(); - data.imag_S21 = port2.imag(); - } else { - // stimulus is present at port 2 - data.real_S12 = port1.real(); - data.imag_S12 = port1.imag(); - data.real_S22 = port2.real(); - data.imag_S22 = port2.imag(); + data.cdBm = settings.cdbm_excitation_start + (settings.cdbm_excitation_stop - settings.cdbm_excitation_start) * pointCnt / (settings.points - 1); } // figure out whether this sweep point is complete stageCnt++; - if(stageCnt == stages) { + if(stageCnt > settings.stages) { // point is complete stageCnt = 0; STM::DispatchToInterrupt(PassOnData); @@ -507,7 +474,7 @@ void VNA::PrintStatus() { HAL_Delay(10); LOG_INFO("Points: %d/%d", pointCnt, settings.points); HAL_Delay(10); - LOG_INFO("Stages: %d/%d", stageCnt, stages); + LOG_INFO("Stages: %d/%d", stageCnt, settings.stages); HAL_Delay(10); LOG_INFO("FPGA status: 0x%04x", FPGA::GetStatus()); }