more flexible USB protocol for VNA settings/measurements
This commit is contained in:
parent
74e6a439af
commit
047f6ce981
@ -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);
|
||||
|
@ -77,7 +77,7 @@ public:
|
||||
// Returns serial numbers of all connected devices
|
||||
static std::set<QString> GetDevices();
|
||||
signals:
|
||||
void DatapointReceived(Protocol::Datapoint);
|
||||
void DatapointReceived(Protocol::VNADatapoint<32>*);
|
||||
void ManualStatusReceived(Protocol::ManualStatusV1);
|
||||
void SpectrumResultReceived(Protocol::SpectrumAnalyzerResult);
|
||||
void AmplitudeCorrectionPointReceived(Protocol::AmplitudeCorrectionPoint);
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include "preferences.h"
|
||||
#include "../VNA_embedded/Application/Communication/Protocol.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
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<double>(res.real_S11, res.imag_S11);
|
||||
m.measurements["S21"] = complex<double>(res.real_S21, res.imag_S21);
|
||||
m.measurements["S12"] = complex<double>(res.real_S12, res.imag_S12);
|
||||
m.measurements["S22"] = complex<double>(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<double> ref = res->getValue(map.second, map.first, true);
|
||||
for(int i=0;i<2;i++) {
|
||||
complex<double> 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::function<vo
|
||||
if(s.excitedPorts.size() == 0) {
|
||||
return setIdle(cb);
|
||||
}
|
||||
|
||||
// create port->stage mapping
|
||||
portStageMapping.clear();
|
||||
for(int i=0;i<s.excitedPorts.size();i++) {
|
||||
portStageMapping[s.excitedPorts[i]] = i;
|
||||
}
|
||||
|
||||
zerospan = (s.freqStart == s.freqStop) && (s.dBmStart == s.dBmStop);
|
||||
auto pref = Preferences::getInstance();
|
||||
if(!isCompoundDevice()) {
|
||||
@ -311,11 +330,13 @@ bool VirtualDevice::setVNA(const VirtualDevice::VNASettings &s, std::function<vo
|
||||
sd.if_bandwidth = s.IFBW;
|
||||
sd.cdbm_excitation_start = s.dBmStart * 100;
|
||||
sd.cdbm_excitation_stop = s.dBmStop * 100;
|
||||
sd.excitePort1 = find(s.excitedPorts.begin(), s.excitedPorts.end(), 1) != s.excitedPorts.end() ? 1 : 0;
|
||||
sd.excitePort2 = find(s.excitedPorts.begin(), s.excitedPorts.end(), 2) != s.excitedPorts.end() ? 1 : 0;
|
||||
sd.stages = s.excitedPorts.size() - 1;
|
||||
sd.port1Stage = find(s.excitedPorts.begin(), s.excitedPorts.end(), 0) - s.excitedPorts.begin();
|
||||
sd.port2Stage = find(s.excitedPorts.begin(), s.excitedPorts.end(), 1) - s.excitedPorts.begin();
|
||||
sd.suppressPeaks = pref.Acquisition.suppressPeaks ? 1 : 0;
|
||||
sd.fixedPowerSetting = pref.Acquisition.adjustPowerLevel || s.dBmStart != s.dBmStop ? 0 : 1;
|
||||
sd.logSweep = s.logSweep ? 1 : 0;
|
||||
sd.syncMode = 0;
|
||||
return devices[0]->Configure(sd, [=](Device::TransmissionResult r){
|
||||
if(cb) {
|
||||
cb(r == Device::TransmissionResult::Ack);
|
||||
@ -372,6 +393,7 @@ bool VirtualDevice::setSA(const VirtualDevice::SASettings &s, std::function<void
|
||||
sd.trackingGeneratorPort = s.trackingPort;
|
||||
sd.trackingGeneratorOffset = s.trackingOffset;
|
||||
sd.trackingPower = s.trackingPower;
|
||||
sd.syncMode = 0;
|
||||
return devices[0]->Configure(sd, [=](Device::TransmissionResult r){
|
||||
if(cb) {
|
||||
cb(r == Device::TransmissionResult::Ack);
|
||||
|
@ -67,7 +67,7 @@ public:
|
||||
double IFBW;
|
||||
int points;
|
||||
bool logSweep;
|
||||
std::vector<int> excitedPorts;
|
||||
std::vector<int> excitedPorts; // port count starts at one
|
||||
};
|
||||
class VNAMeasurement {
|
||||
public:
|
||||
@ -177,12 +177,15 @@ private:
|
||||
Status status;
|
||||
bool isCompound;
|
||||
std::vector<Device*> devices;
|
||||
std::vector<int> portMapping;
|
||||
bool zerospan;
|
||||
|
||||
std::map<Device*, Device::TransmissionResult> results;
|
||||
|
||||
CompoundDevice *cdev;
|
||||
|
||||
std::map<int, std::vector<Protocol::VNADatapoint<32>*>> compoundDataBuffer;
|
||||
|
||||
std::map<int, int> portStageMapping; // maps from excitedPort (count starts at zero) to stage (count starts at zero)
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(VirtualDevice::Status)
|
||||
|
@ -157,6 +157,7 @@ std::vector<Trace *> 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
|
||||
|
@ -925,11 +925,11 @@ void VNA::SettingsChanged(bool resetTraces, std::function<void (bool)> 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;i<VirtualDevice::getInfo(window->getDevice()).ports;i++) {
|
||||
s.excitedPorts.push_back(i);
|
||||
}
|
||||
} else {
|
||||
for(int i=1;i<=VirtualDevice::getInfo(window->getDevice()).ports;i++) {
|
||||
for(int i=0;i<VirtualDevice::getInfo(window->getDevice()).ports;i++) {
|
||||
if(traceModel.PortExcitationRequired(i))
|
||||
s.excitedPorts.push_back(i);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -1,13 +1,110 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <complex>
|
||||
|
||||
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<int s> 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<double> 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<num_values;i++) {
|
||||
if(descr_values[i] >> 5 != stage) {
|
||||
continue;
|
||||
}
|
||||
if((descr_values[i] & sourceMask) != sourceMask) {
|
||||
continue;
|
||||
}
|
||||
return std::complex<double>(real_values[i], imag_values[i]);
|
||||
}
|
||||
return std::numeric_limits<std::complex<double>>::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;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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<float>(result.P1I, result.P1Q);
|
||||
auto port2_raw = std::complex<float>(result.P2I, result.P2Q);
|
||||
auto ref = std::complex<float>(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());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user