mirror of
https://github.com/jankae/LibreVNA.git
synced 2026-04-05 14:35:23 +00:00
WIP: synchronization
This commit is contained in:
parent
7b3aa6e158
commit
73e26a25c4
41 changed files with 439 additions and 163 deletions
|
|
@ -423,8 +423,9 @@ void AmplitudeCalDialog::AutomaticMeasurementDialog()
|
|||
}
|
||||
}
|
||||
|
||||
void AmplitudeCalDialog::ReceivedMeasurement(Protocol::SpectrumAnalyzerResult res)
|
||||
void AmplitudeCalDialog::ReceivedMeasurement(Device *dev, Protocol::SpectrumAnalyzerResult res)
|
||||
{
|
||||
Q_UNUSED(dev)
|
||||
MeasurementResult m = {.port1 = Util::SparamTodB(res.port1), .port2 = Util::SparamTodB(res.port2)};
|
||||
sweepMeasurements.push_back(m);
|
||||
if(res.pointNum == automaticSweepPoints - 1) {
|
||||
|
|
@ -529,8 +530,9 @@ void AmplitudeCalDialog::SetupNextAutomaticPoint(bool isSourceCal)
|
|||
sweepMeasurements.reserve(automaticSweepPoints);
|
||||
}
|
||||
|
||||
void AmplitudeCalDialog::ReceivedAutomaticMeasurementResult(Protocol::SpectrumAnalyzerResult res)
|
||||
void AmplitudeCalDialog::ReceivedAutomaticMeasurementResult(Device *dev, Protocol::SpectrumAnalyzerResult res)
|
||||
{
|
||||
Q_UNUSED(dev)
|
||||
if(res.pointNum != automaticSweepPoints - 1) {
|
||||
// ignore everything except end of sweep
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ protected slots:
|
|||
bool AddPoint(double frequency);
|
||||
void AddPointDialog();
|
||||
void AutomaticMeasurementDialog();
|
||||
void ReceivedMeasurement(Protocol::SpectrumAnalyzerResult res);
|
||||
void ReceivedMeasurement(Device *dev, Protocol::SpectrumAnalyzerResult res);
|
||||
signals:
|
||||
void pointsUpdated();
|
||||
void newPointCreated(CorrectionPoint& p);
|
||||
|
|
@ -108,7 +108,7 @@ protected:
|
|||
CalibrationMode mode;
|
||||
|
||||
void SetupNextAutomaticPoint(bool isSourceCal);
|
||||
void ReceivedAutomaticMeasurementResult(Protocol::SpectrumAnalyzerResult res);
|
||||
void ReceivedAutomaticMeasurementResult(Device *dev, Protocol::SpectrumAnalyzerResult res);
|
||||
struct {
|
||||
QDialog *dialog;
|
||||
std::vector<CorrectionPoint> points;
|
||||
|
|
|
|||
|
|
@ -122,6 +122,15 @@ bool TileWidget::allLimitsPassing()
|
|||
}
|
||||
}
|
||||
|
||||
void TileWidget::setSplitPercentage(int percentage)
|
||||
{
|
||||
if(!isSplit) {
|
||||
return;
|
||||
}
|
||||
splitter->setStretchFactor(0, percentage);
|
||||
splitter->setStretchFactor(1, 100 - percentage);
|
||||
}
|
||||
|
||||
void TileWidget::splitVertically(bool moveContentToSecondChild)
|
||||
{
|
||||
if(isSplit) {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ public:
|
|||
// check potential trace limits on graphs, only returns true if all traces in all graphs are within limits
|
||||
bool allLimitsPassing();
|
||||
|
||||
void setSplitPercentage(int percentage);
|
||||
|
||||
public slots:
|
||||
void splitVertically(bool moveContentToSecondChild = false);
|
||||
void splitHorizontally(bool moveContentToSecondChild = false);
|
||||
|
|
|
|||
|
|
@ -326,7 +326,6 @@ std::set<QString> Device::GetDevices()
|
|||
|
||||
void Device::SetTrigger(bool set)
|
||||
{
|
||||
qDebug() << "Trigger" << set << "to" << this;
|
||||
if(set) {
|
||||
SendCommandWithoutPayload(Protocol::PacketType::SetTrigger);
|
||||
} else {
|
||||
|
|
@ -479,13 +478,13 @@ void Device::ReceivedData()
|
|||
dataBuffer->removeBytes(handled_len);
|
||||
switch(packet.type) {
|
||||
case Protocol::PacketType::VNADatapoint:
|
||||
emit DatapointReceived(packet.VNAdatapoint);
|
||||
emit DatapointReceived(this, packet.VNAdatapoint);
|
||||
break;
|
||||
case Protocol::PacketType::ManualStatusV1:
|
||||
emit ManualStatusReceived(packet.manualStatusV1);
|
||||
break;
|
||||
case Protocol::PacketType::SpectrumAnalyzerResult:
|
||||
emit SpectrumResultReceived(packet.spectrumResult);
|
||||
emit SpectrumResultReceived(this, packet.spectrumResult);
|
||||
break;
|
||||
case Protocol::PacketType::SourceCalPoint:
|
||||
case Protocol::PacketType::ReceiverCalPoint:
|
||||
|
|
@ -500,11 +499,11 @@ void Device::ReceivedData()
|
|||
info = packet.info;
|
||||
}
|
||||
infoValid = true;
|
||||
emit DeviceInfoUpdated();
|
||||
emit DeviceInfoUpdated(this);
|
||||
break;
|
||||
case Protocol::PacketType::DeviceStatusV1:
|
||||
status.v1 = packet.statusV1;
|
||||
emit DeviceStatusUpdated();
|
||||
emit DeviceStatusUpdated(this);
|
||||
break;
|
||||
case Protocol::PacketType::Ack:
|
||||
emit AckReceived();
|
||||
|
|
@ -518,11 +517,9 @@ void Device::ReceivedData()
|
|||
emit FrequencyCorrectionReceived(packet.frequencyCorrection.ppm);
|
||||
break;
|
||||
case Protocol::PacketType::SetTrigger:
|
||||
qDebug() << "Trigger" << true << "from" << this;
|
||||
emit TriggerReceived(true);
|
||||
break;
|
||||
case Protocol::PacketType::ClearTrigger:
|
||||
qDebug() << "Trigger" << false << "from" << this;
|
||||
emit TriggerReceived(false);
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -78,13 +78,13 @@ public:
|
|||
// Returns serial numbers of all connected devices
|
||||
static std::set<QString> GetDevices();
|
||||
signals:
|
||||
void DatapointReceived(Protocol::VNADatapoint<32>*);
|
||||
void DatapointReceived(Device*, Protocol::VNADatapoint<32>*);
|
||||
void ManualStatusReceived(Protocol::ManualStatusV1);
|
||||
void SpectrumResultReceived(Protocol::SpectrumAnalyzerResult);
|
||||
void SpectrumResultReceived(Device*, Protocol::SpectrumAnalyzerResult);
|
||||
void AmplitudeCorrectionPointReceived(Protocol::AmplitudeCorrectionPoint);
|
||||
void FrequencyCorrectionReceived(float ppm);
|
||||
void DeviceInfoUpdated();
|
||||
void DeviceStatusUpdated();
|
||||
void DeviceInfoUpdated(Device*);
|
||||
void DeviceStatusUpdated(Device*);
|
||||
void ConnectionLost();
|
||||
void AckReceived();
|
||||
void NackReceived();
|
||||
|
|
|
|||
|
|
@ -147,18 +147,10 @@ VirtualDevice::VirtualDevice(QString serial)
|
|||
connect(dev, &Device::LogLineReceived, [=](QString line){
|
||||
emit LogLineReceived(line.prepend(dev->serial()+": "));
|
||||
});
|
||||
connect(dev, &Device::DeviceInfoUpdated, [=](){
|
||||
compoundInfoUpdated(dev);
|
||||
});
|
||||
connect(dev, &Device::DeviceStatusUpdated, [=](){
|
||||
compoundStatusUpdated(dev);
|
||||
});
|
||||
connect(dev, &Device::DatapointReceived, [=](Protocol::VNADatapoint<32> *data){
|
||||
compoundDatapointReceivecd(data, dev);
|
||||
});
|
||||
connect(dev, &Device::SpectrumResultReceived, [=](Protocol::SpectrumAnalyzerResult res) {
|
||||
compoundSpectrumResultReceived(res, dev);
|
||||
});
|
||||
connect(dev, &Device::DeviceInfoUpdated, this, &VirtualDevice::compoundInfoUpdated, Qt::QueuedConnection);
|
||||
connect(dev, &Device::DeviceStatusUpdated, this, &VirtualDevice::compoundStatusUpdated, Qt::QueuedConnection);
|
||||
connect(dev, &Device::DatapointReceived, this, &VirtualDevice::compoundDatapointReceivecd, Qt::QueuedConnection);
|
||||
connect(dev, &Device::SpectrumResultReceived, this, &VirtualDevice::compoundSpectrumResultReceived, Qt::QueuedConnection);
|
||||
}
|
||||
if(cdev->sync == CompoundDevice::Synchronization::USB) {
|
||||
// create trigger connections for USB synchronization
|
||||
|
|
@ -283,6 +275,7 @@ bool VirtualDevice::setVNA(const VirtualDevice::VNASettings &s, std::function<vo
|
|||
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.syncMode = 0;
|
||||
sd.syncMaster = 0;
|
||||
return devices[0]->Configure(sd, [=](Device::TransmissionResult r){
|
||||
if(cb) {
|
||||
cb(r == Device::TransmissionResult::Ack);
|
||||
|
|
@ -306,6 +299,7 @@ bool VirtualDevice::setVNA(const VirtualDevice::VNASettings &s, std::function<vo
|
|||
for(unsigned int i=0;i<devices.size();i++) {
|
||||
sd.port1Stage = CompoundDevice::PortMapping::findActiveStage(activeMapping, i, 0);
|
||||
sd.port2Stage = CompoundDevice::PortMapping::findActiveStage(activeMapping, i, 1);
|
||||
sd.syncMaster = i == 0 ? 1 : 0;
|
||||
success &= devices[i]->Configure(sd, [=](Device::TransmissionResult r){
|
||||
if(cb) {
|
||||
results[devices[i]] = r;
|
||||
|
|
@ -342,34 +336,65 @@ bool VirtualDevice::setSA(const VirtualDevice::SASettings &s, std::function<void
|
|||
}
|
||||
zerospan = s.freqStart == s.freqStop;
|
||||
auto pref = Preferences::getInstance();
|
||||
Protocol::SpectrumAnalyzerSettings sd;
|
||||
sd.f_start = s.freqStart;
|
||||
sd.f_stop = s.freqStop;
|
||||
sd.pointNum = s.points;
|
||||
sd.RBW = s.RBW;
|
||||
sd.WindowType = (int) s.window;
|
||||
sd.SignalID = s.signalID ? 1 : 0;
|
||||
sd.Detector = (int) s.detector;
|
||||
sd.UseDFT = 0;
|
||||
if(!s.trackingGenerator && pref.Acquisition.useDFTinSAmode && s.RBW <= pref.Acquisition.RBWLimitForDFT) {
|
||||
sd.UseDFT = 1;
|
||||
}
|
||||
sd.applyReceiverCorrection = 1;
|
||||
sd.trackingGeneratorOffset = s.trackingOffset;
|
||||
sd.trackingPower = s.trackingPower;
|
||||
|
||||
if(!isCompoundDevice()) {
|
||||
Protocol::SpectrumAnalyzerSettings sd;
|
||||
sd.f_start = s.freqStart;
|
||||
sd.f_stop = s.freqStop;
|
||||
sd.pointNum = s.points;
|
||||
sd.RBW = s.RBW;
|
||||
sd.WindowType = (int) s.window;
|
||||
sd.SignalID = s.signalID ? 1 : 0;
|
||||
sd.Detector = (int) s.detector;
|
||||
sd.UseDFT = 0;
|
||||
if(!s.trackingGenerator && pref.Acquisition.useDFTinSAmode && s.RBW <= pref.Acquisition.RBWLimitForDFT) {
|
||||
sd.UseDFT = 1;
|
||||
}
|
||||
sd.applyReceiverCorrection = 1;
|
||||
sd.trackingGenerator = s.trackingGenerator ? 1 : 0;
|
||||
sd.applySourceCorrection = 1;
|
||||
sd.trackingGeneratorPort = s.trackingPort;
|
||||
sd.trackingGeneratorOffset = s.trackingOffset;
|
||||
sd.trackingPower = s.trackingPower;
|
||||
sd.syncMode = 0;
|
||||
sd.syncMaster = 0;
|
||||
return devices[0]->Configure(sd, [=](Device::TransmissionResult r){
|
||||
if(cb) {
|
||||
cb(r == Device::TransmissionResult::Ack);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// TODO
|
||||
return false;
|
||||
// set the synchronization mode
|
||||
switch(cdev->sync) {
|
||||
case CompoundDevice::Synchronization::USB: sd.syncMode = 1; break;
|
||||
case CompoundDevice::Synchronization::ExtRef: sd.syncMode = 2; break;
|
||||
case CompoundDevice::Synchronization::Trigger: sd.syncMode = 3; break;
|
||||
}
|
||||
// Configure the devices
|
||||
results.clear();
|
||||
bool success = true;
|
||||
for(unsigned int i=0;i<devices.size();i++) {
|
||||
if(s.trackingGenerator) {
|
||||
if(CompoundDevice::PortMapping::findActiveStage(cdev->portMapping, i, 0) == s.trackingPort) {
|
||||
sd.trackingGenerator = 1;
|
||||
sd.trackingGeneratorPort = 0;
|
||||
} else if(CompoundDevice::PortMapping::findActiveStage(cdev->portMapping, i, 1) == s.trackingPort) {
|
||||
sd.trackingGenerator = 1;
|
||||
sd.trackingGeneratorPort = 1;
|
||||
}
|
||||
} else {
|
||||
// not used
|
||||
sd.trackingGenerator = 0;
|
||||
sd.trackingGeneratorPort = 0;
|
||||
}
|
||||
sd.syncMaster = i == 0 ? 1 : 0;
|
||||
success &= devices[i]->Configure(sd, [=](Device::TransmissionResult r){
|
||||
if(cb) {
|
||||
results[devices[i]] = r;
|
||||
checkIfAllTransmissionsComplete(cb);
|
||||
}
|
||||
});
|
||||
}
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -520,8 +545,9 @@ VirtualDevice *VirtualDevice::getConnected()
|
|||
return connected;
|
||||
}
|
||||
|
||||
void VirtualDevice::singleDatapointReceived(Protocol::VNADatapoint<32> *res)
|
||||
void VirtualDevice::singleDatapointReceived(Device *dev, Protocol::VNADatapoint<32> *res)
|
||||
{
|
||||
Q_UNUSED(dev)
|
||||
VNAMeasurement m;
|
||||
m.pointNum = res->pointNum;
|
||||
m.Z0 = 50.0;
|
||||
|
|
@ -548,7 +574,7 @@ void VirtualDevice::singleDatapointReceived(Protocol::VNADatapoint<32> *res)
|
|||
emit VNAmeasurementReceived(m);
|
||||
}
|
||||
|
||||
void VirtualDevice::compoundDatapointReceivecd(Protocol::VNADatapoint<32> *data, Device *dev)
|
||||
void VirtualDevice::compoundDatapointReceivecd(Device *dev, Protocol::VNADatapoint<32> *data)
|
||||
{
|
||||
if(!compoundVNABuffer.count(data->pointNum)) {
|
||||
compoundVNABuffer[data->pointNum] = std::map<Device*, Protocol::VNADatapoint<32>*>();
|
||||
|
|
@ -600,18 +626,25 @@ void VirtualDevice::compoundDatapointReceivecd(Protocol::VNADatapoint<32> *data,
|
|||
|
||||
emit VNAmeasurementReceived(m);
|
||||
|
||||
// Clear this and all incomplete older datapoint buffers
|
||||
for(auto p : compoundVNABuffer) {
|
||||
for(auto d : p.second) {
|
||||
delete d.second;
|
||||
// Clear this and all (incomplete) older datapoint buffers
|
||||
int pointNum = data->pointNum;
|
||||
auto it = compoundVNABuffer.begin();
|
||||
while(it != compoundVNABuffer.end()) {
|
||||
if(it->first <= pointNum) {
|
||||
for(auto d : it->second) {
|
||||
delete d.second;
|
||||
}
|
||||
it = compoundVNABuffer.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
compoundVNABuffer.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualDevice::singleSpectrumResultReceived(Protocol::SpectrumAnalyzerResult res)
|
||||
void VirtualDevice::singleSpectrumResultReceived(Device *dev, Protocol::SpectrumAnalyzerResult res)
|
||||
{
|
||||
Q_UNUSED(dev)
|
||||
SAMeasurement m;
|
||||
m.pointNum = res.pointNum;
|
||||
if(zerospan) {
|
||||
|
|
@ -624,9 +657,47 @@ void VirtualDevice::singleSpectrumResultReceived(Protocol::SpectrumAnalyzerResul
|
|||
emit SAmeasurementReceived(m);
|
||||
}
|
||||
|
||||
void VirtualDevice::compoundSpectrumResultReceived(Protocol::SpectrumAnalyzerResult res, Device *dev)
|
||||
void VirtualDevice::compoundSpectrumResultReceived(Device *dev, Protocol::SpectrumAnalyzerResult res)
|
||||
{
|
||||
if(!compoundSABuffer.count(res.pointNum)) {
|
||||
compoundSABuffer[res.pointNum] = std::map<Device*, Protocol::SpectrumAnalyzerResult>();
|
||||
}
|
||||
auto &buf = compoundSABuffer[res.pointNum];
|
||||
buf[dev] = res;
|
||||
if(buf.size() == devices.size()) {
|
||||
// Got datapoints from all devices, can create merged VNA result
|
||||
SAMeasurement m;
|
||||
m.pointNum = res.pointNum;
|
||||
if(zerospan) {
|
||||
m.us = res.us;
|
||||
} else {
|
||||
m.frequency = res.frequency;
|
||||
}
|
||||
// assemble data
|
||||
for(unsigned int port=0;port<cdev->portMapping.size();port++) {
|
||||
auto device = devices[cdev->portMapping[port].device];
|
||||
auto devicePort = cdev->portMapping[port].port;
|
||||
|
||||
QString name = "PORT"+QString::number(port+1);
|
||||
if(devicePort == 0) {
|
||||
m.measurements[name] = buf[device].port1;
|
||||
} else {
|
||||
m.measurements[name] = buf[device].port2;
|
||||
}
|
||||
}
|
||||
|
||||
emit SAmeasurementReceived(m);
|
||||
|
||||
// Clear this and all (incomplete) older datapoint buffers
|
||||
auto it = compoundSABuffer.begin();
|
||||
while(it != compoundSABuffer.end()) {
|
||||
if(it->first <= res.pointNum) {
|
||||
it = compoundSABuffer.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualDevice::compoundInfoUpdated(Device *dev)
|
||||
|
|
@ -778,7 +849,7 @@ VirtualDevice::Info::Info(Device *dev)
|
|||
Limits.mindBm = (double) info.limits_cdbm_min / 100;
|
||||
Limits.maxdBm = (double) info.limits_cdbm_max / 100;
|
||||
Limits.minRBW = info.limits_minRBW;
|
||||
Limits.maxRBW = info.limits_minRBW;
|
||||
Limits.maxRBW = info.limits_maxRBW;
|
||||
}
|
||||
|
||||
void VirtualDevice::Info::subset(const VirtualDevice::Info &merge)
|
||||
|
|
|
|||
|
|
@ -141,7 +141,6 @@ public:
|
|||
struct {
|
||||
// for non-zero span
|
||||
double frequency;
|
||||
double cdbm;
|
||||
};
|
||||
struct {
|
||||
// for zero span
|
||||
|
|
@ -184,10 +183,10 @@ signals:
|
|||
void NeedsFirmwareUpdate(int usedProtocol, int requiredProtocol);
|
||||
|
||||
private slots:
|
||||
void singleDatapointReceived(Protocol::VNADatapoint<32> *res);
|
||||
void compoundDatapointReceivecd(Protocol::VNADatapoint<32> *data, Device *dev);
|
||||
void singleSpectrumResultReceived(Protocol::SpectrumAnalyzerResult res);
|
||||
void compoundSpectrumResultReceived(Protocol::SpectrumAnalyzerResult res, Device *dev);
|
||||
void singleDatapointReceived(Device *dev, Protocol::VNADatapoint<32> *res);
|
||||
void compoundDatapointReceivecd(Device *dev, Protocol::VNADatapoint<32> *data);
|
||||
void singleSpectrumResultReceived(Device *dev, Protocol::SpectrumAnalyzerResult res);
|
||||
void compoundSpectrumResultReceived(Device *dev, Protocol::SpectrumAnalyzerResult res);
|
||||
void compoundInfoUpdated(Device *dev);
|
||||
void compoundStatusUpdated(Device *dev);
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -53,6 +53,11 @@ void Generator::fromJSON(nlohmann::json j)
|
|||
central->fromJSON(j);
|
||||
}
|
||||
|
||||
void Generator::preset()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Generator::updateDevice()
|
||||
{
|
||||
if(!window->getDevice() || isActive != true) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ public:
|
|||
|
||||
void setAveragingMode(Averaging::Mode mode) override {Q_UNUSED(mode)}
|
||||
|
||||
void preset() override;
|
||||
|
||||
private slots:
|
||||
void updateDevice();
|
||||
|
||||
|
|
|
|||
|
|
@ -60,20 +60,7 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
|
|||
traceModel.setSource(TraceModel::DataSource::SA);
|
||||
|
||||
// Create default traces
|
||||
auto tPort1 = new Trace("Port1", Qt::yellow);
|
||||
tPort1->fromLivedata(Trace::LivedataType::Overwrite, "PORT1");
|
||||
traceModel.addTrace(tPort1);
|
||||
auto tPort2 = new Trace("Port2", Qt::blue);
|
||||
tPort2->fromLivedata(Trace::LivedataType::Overwrite, "PORT2");
|
||||
traceModel.addTrace(tPort2);
|
||||
|
||||
auto traceXY = new TraceXYPlot(traceModel);
|
||||
traceXY->enableTrace(tPort1, true);
|
||||
traceXY->enableTrace(tPort2, true);
|
||||
traceXY->setYAxis(0, YAxis::Type::Magnitude, false, false, -120,0,10);
|
||||
traceXY->setYAxis(1, YAxis::Type::Disabled, false, true, 0,0,1);
|
||||
|
||||
central->setPlot(traceXY);
|
||||
preset();
|
||||
|
||||
// Create menu entries and connections
|
||||
// Sweep toolbar
|
||||
|
|
@ -1153,11 +1140,42 @@ void SpectrumAnalyzer::StoreSweepSettings()
|
|||
s.setValue("SASignalID", static_cast<bool>(settings.signalID));
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::createDefaultTracesAndGraphs(int ports)
|
||||
{
|
||||
central->clear();
|
||||
auto traceXY = new TraceXYPlot(traceModel);
|
||||
traceXY->setYAxis(0, YAxis::Type::Magnitude, false, false, -120,0,10);
|
||||
traceXY->setYAxis(1, YAxis::Type::Disabled, false, true, 0,0,1);
|
||||
traceXY->updateSpan(settings.freqStart, settings.freqStop);
|
||||
|
||||
central->setPlot(traceXY);
|
||||
|
||||
QColor defaultColors[] = {Qt::yellow, Qt::blue, Qt::red, Qt::green, Qt::gray, Qt::cyan, Qt::magenta, Qt::white};
|
||||
|
||||
for(int i=0;i<ports;i++) {
|
||||
QString param = "PORT"+QString::number(i+1);
|
||||
auto trace = new Trace(param, defaultColors[i], param);
|
||||
traceModel.addTrace(trace);
|
||||
traceXY->enableTrace(trace, true);
|
||||
}
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::setAveragingMode(Averaging::Mode mode)
|
||||
{
|
||||
average.setMode(mode);
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::preset()
|
||||
{
|
||||
for(auto t : traceModel.getTraces()) {
|
||||
if(Trace::isSAParameter(t->name())) {
|
||||
traceModel.removeTrace(t);
|
||||
}
|
||||
}
|
||||
// Create default traces
|
||||
createDefaultTracesAndGraphs(VirtualDevice::getInfo(window->getDevice()).ports);
|
||||
}
|
||||
|
||||
QString SpectrumAnalyzer::WindowToString(VirtualDevice::SASettings::Window w)
|
||||
{
|
||||
switch(w) {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ public:
|
|||
void updateGraphColors();
|
||||
void setAveragingMode(Averaging::Mode mode) override;
|
||||
|
||||
void preset() override;
|
||||
|
||||
private:
|
||||
static QString WindowToString(VirtualDevice::SASettings::Window w);
|
||||
|
|
@ -74,6 +75,8 @@ private:
|
|||
void LoadSweepSettings();
|
||||
void StoreSweepSettings();
|
||||
|
||||
void createDefaultTracesAndGraphs(int ports);
|
||||
|
||||
VirtualDevice::SASettings settings;
|
||||
bool changingSettings;
|
||||
unsigned int averages;
|
||||
|
|
|
|||
|
|
@ -48,11 +48,29 @@ void TraceModel::removeTrace(unsigned int index)
|
|||
}
|
||||
}
|
||||
|
||||
void TraceModel::removeTrace(Trace *t)
|
||||
{
|
||||
auto index = findIndex(t);
|
||||
if(index >= 0) {
|
||||
removeTrace(index);
|
||||
}
|
||||
}
|
||||
|
||||
Trace *TraceModel::trace(unsigned int index)
|
||||
{
|
||||
return traces.at(index);
|
||||
}
|
||||
|
||||
int TraceModel::findIndex(Trace *t)
|
||||
{
|
||||
for(int i=0;i<traces.size();i++) {
|
||||
if(traces[i] == t) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void TraceModel::toggleVisibility(unsigned int index)
|
||||
{
|
||||
if (index < traces.size()) {
|
||||
|
|
@ -184,7 +202,7 @@ void TraceModel::fromJSON(nlohmann::json j)
|
|||
{
|
||||
// clear old traces
|
||||
while(traces.size()) {
|
||||
removeTrace(0);
|
||||
removeTrace((int) 0);
|
||||
}
|
||||
for(auto jt : j) {
|
||||
auto trace = new Trace();
|
||||
|
|
|
|||
|
|
@ -33,7 +33,9 @@ public:
|
|||
|
||||
void addTrace(Trace *t);
|
||||
void removeTrace(unsigned int index);
|
||||
void removeTrace(Trace *t);
|
||||
Trace *trace(unsigned int index);
|
||||
int findIndex(Trace *t);
|
||||
void toggleVisibility(unsigned int index);
|
||||
void togglePause(unsigned int index);
|
||||
void toggleMath(unsigned int index);
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ class TraceSmithChart : public TracePlot
|
|||
public:
|
||||
TraceSmithChart(TraceModel &model, QWidget *parent = 0);
|
||||
|
||||
virtual Type getType() override { return Type::SmithChart;};
|
||||
virtual Type getType() override { return Type::SmithChart;}
|
||||
|
||||
virtual nlohmann::json toJSON() override;
|
||||
virtual void fromJSON(nlohmann::json j) override;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ public:
|
|||
QVariant value() {
|
||||
return QVariant(variant.type(), ptr);
|
||||
}
|
||||
void* getPtr(){return ptr;}
|
||||
private:
|
||||
void *ptr;
|
||||
QVariant variant;
|
||||
|
|
|
|||
|
|
@ -71,40 +71,10 @@ VNA::VNA(AppWindow *window, QString name)
|
|||
traceModel.setSource(TraceModel::DataSource::VNA);
|
||||
|
||||
// Create default traces
|
||||
auto tS11 = new Trace("S11", Qt::yellow);
|
||||
tS11->fromLivedata(Trace::LivedataType::Overwrite, "S11");
|
||||
traceModel.addTrace(tS11);
|
||||
auto tS12 = new Trace("S12", Qt::blue);
|
||||
tS12->fromLivedata(Trace::LivedataType::Overwrite, "S12");
|
||||
traceModel.addTrace(tS12);
|
||||
auto tS21 = new Trace("S21", Qt::green);
|
||||
tS21->fromLivedata(Trace::LivedataType::Overwrite, "S21");
|
||||
traceModel.addTrace(tS21);
|
||||
auto tS22 = new Trace("S22", Qt::red);
|
||||
tS22->fromLivedata(Trace::LivedataType::Overwrite, "S22");
|
||||
traceModel.addTrace(tS22);
|
||||
|
||||
auto tracesmith1 = new TraceSmithChart(traceModel);
|
||||
tracesmith1->enableTrace(tS11, true);
|
||||
|
||||
auto tracesmith2 = new TraceSmithChart(traceModel);
|
||||
tracesmith2->enableTrace(tS22, true);
|
||||
|
||||
auto traceXY1 = new TraceXYPlot(traceModel);
|
||||
traceXY1->enableTrace(tS12, true);
|
||||
auto traceXY2 = new TraceXYPlot(traceModel);
|
||||
traceXY2->enableTrace(tS21, true);
|
||||
createDefaultTracesAndGraphs(2);
|
||||
|
||||
connect(&traceModel, &TraceModel::requiredExcitation, this, &VNA::ExcitationRequired);
|
||||
|
||||
central->splitVertically();
|
||||
central->Child1()->splitHorizontally();
|
||||
central->Child2()->splitHorizontally();
|
||||
central->Child1()->Child1()->setPlot(tracesmith1);
|
||||
central->Child1()->Child2()->setPlot(traceXY1);
|
||||
central->Child2()->Child1()->setPlot(traceXY2);
|
||||
central->Child2()->Child2()->setPlot(tracesmith2);
|
||||
|
||||
// Create menu entries and connections
|
||||
auto calMenu = new QMenu("Calibration", window);
|
||||
window->menuBar()->insertMenu(window->getUi()->menuWindow->menuAction(), calMenu);
|
||||
|
|
@ -924,7 +894,7 @@ void VNA::SettingsChanged(bool resetTraces, std::function<void (bool)> cb)
|
|||
// assemble VNA protocol settings
|
||||
VirtualDevice::VNASettings s = {};
|
||||
s.IFBW = settings.bandwidth;
|
||||
if(Preferences::getInstance().Acquisition.alwaysExciteBothPorts) {
|
||||
if(Preferences::getInstance().Acquisition.alwaysExciteAllPorts) {
|
||||
for(int i=0;i<VirtualDevice::getInfo(window->getDevice()).ports;i++) {
|
||||
s.excitedPorts.push_back(i);
|
||||
}
|
||||
|
|
@ -1183,7 +1153,7 @@ void VNA::SetAveraging(unsigned int averages)
|
|||
|
||||
void VNA::ExcitationRequired()
|
||||
{
|
||||
if(!Preferences::getInstance().Acquisition.alwaysExciteBothPorts) {
|
||||
if(!Preferences::getInstance().Acquisition.alwaysExciteAllPorts) {
|
||||
for(int i=1;i<VirtualDevice::getInfo(window->getDevice()).ports;i++) {
|
||||
auto required = traceModel.PortExcitationRequired(i);
|
||||
auto set = find(settings.excitedPorts.begin(), settings.excitedPorts.end(), i) != settings.excitedPorts.end();
|
||||
|
|
@ -1624,6 +1594,92 @@ void VNA::UpdateCalWidget()
|
|||
calLabel->setToolTip(getCalToolTip());
|
||||
}
|
||||
|
||||
void VNA::createDefaultTracesAndGraphs(int ports)
|
||||
{
|
||||
auto getDefaultColor = [](int ports, int i, int j)->QColor {
|
||||
// Default colors for up to four ports, ensures that e.g. S21 always has the same color
|
||||
const array<vector<QColor>, 4> defaultColors = {{
|
||||
{Qt::yellow},
|
||||
{Qt::yellow, Qt::blue, Qt::green, Qt::red},
|
||||
{Qt::yellow, Qt::blue, Qt::cyan, Qt::green, Qt::red, Qt::darkGreen, Qt::darkBlue, Qt::darkYellow, Qt::magenta},
|
||||
{Qt::yellow, Qt::blue, Qt::cyan, Qt::darkCyan, Qt::green, Qt::red, Qt::darkGreen, Qt::gray, Qt::darkBlue, Qt::darkYellow, Qt::magenta, Qt::darkMagenta, Qt::cyan, Qt::darkGray, Qt::lightGray, Qt::darkRed},
|
||||
}};
|
||||
|
||||
if(ports >= 1 && ports <= 4) {
|
||||
return defaultColors[ports-1][i*ports+j];
|
||||
} else {
|
||||
// not enough predefined colors available for all ports, just cycle through list
|
||||
const array<QColor, 16> list = {{
|
||||
Qt::yellow, Qt::blue, Qt::green, Qt::red, Qt::cyan, Qt::magenta, Qt::yellow, Qt::darkRed, Qt::darkGreen, Qt::darkBlue, Qt::gray, Qt::darkCyan, Qt::darkMagenta, Qt::darkYellow, Qt::darkGray, Qt::lightGray
|
||||
}};
|
||||
auto index = (i*ports+j) % list.size();
|
||||
return list[index];
|
||||
}
|
||||
};
|
||||
|
||||
vector<vector<TracePlot*>> plots;
|
||||
for(int i=0;i<ports;i++) {
|
||||
plots.push_back(vector<TracePlot*>());
|
||||
for(int j=0;j<ports;j++) {
|
||||
QString param = "S"+QString::number(i+1)+QString::number(j+1);
|
||||
auto trace = new Trace(param, getDefaultColor(ports, i, j), param);
|
||||
traceModel.addTrace(trace);
|
||||
TracePlot *plot;
|
||||
if(i == j) {
|
||||
plot = new TraceSmithChart(traceModel);
|
||||
} else {
|
||||
plot = new TraceXYPlot(traceModel);
|
||||
}
|
||||
plot->updateSpan(settings.Freq.start, settings.Freq.stop);
|
||||
plot->enableTrace(trace, true);
|
||||
plots[i].push_back(plot);
|
||||
}
|
||||
}
|
||||
// Add created graphs to tiles
|
||||
central->clear();
|
||||
TileWidget *tile = central;
|
||||
for(int i=0;i<ports;i++) {
|
||||
TileWidget *row;
|
||||
if(i != ports - 1) {
|
||||
// this is not the last row, split tile
|
||||
tile->splitVertically();
|
||||
row = tile->Child1();
|
||||
tile = tile->Child2();
|
||||
} else {
|
||||
row = tile;
|
||||
}
|
||||
for(int j=0;j<ports;j++) {
|
||||
TileWidget *graphTile;
|
||||
if(j != ports - 1) {
|
||||
row->splitHorizontally();
|
||||
graphTile = row->Child1();
|
||||
row = row->Child2();
|
||||
} else {
|
||||
graphTile = row;
|
||||
}
|
||||
graphTile->setPlot(plots[i][j]);
|
||||
}
|
||||
}
|
||||
if(ports >= 3) {
|
||||
// default split at the middle does not result in all plots being the same size, adjust
|
||||
tile = central;
|
||||
for(int i=0;i<ports;i++) {
|
||||
TileWidget *rowTile;
|
||||
if(i < ports - 1) {
|
||||
tile->setSplitPercentage(100 / (ports - i));
|
||||
rowTile = tile->Child1();
|
||||
} else {
|
||||
rowTile = tile;
|
||||
}
|
||||
for(int j=0;j<ports-1;j++) {
|
||||
rowTile->setSplitPercentage(100 / (ports - j));
|
||||
rowTile = rowTile->Child2();
|
||||
}
|
||||
tile = tile->Child2();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VNA::EnableDeembedding(bool enable)
|
||||
{
|
||||
deembedding_active = enable;
|
||||
|
|
@ -1637,6 +1693,17 @@ void VNA::setAveragingMode(Averaging::Mode mode)
|
|||
average.setMode(mode);
|
||||
}
|
||||
|
||||
void VNA::preset()
|
||||
{
|
||||
for(auto t : traceModel.getTraces()) {
|
||||
if(Trace::isVNAParameter(t->name())) {
|
||||
traceModel.removeTrace(t);
|
||||
}
|
||||
}
|
||||
// Create default traces
|
||||
createDefaultTracesAndGraphs(VirtualDevice::getInfo(window->getDevice()).ports);
|
||||
}
|
||||
|
||||
QString VNA::SweepTypeToString(VNA::SweepType sw)
|
||||
{
|
||||
switch(sw) {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ public:
|
|||
void updateGraphColors();
|
||||
void setAveragingMode(Averaging::Mode mode) override;
|
||||
|
||||
void preset() override;
|
||||
|
||||
enum class SweepType {
|
||||
Frequency = 0,
|
||||
Power = 1,
|
||||
|
|
@ -121,6 +123,8 @@ private:
|
|||
void StopSweep();
|
||||
void StartCalibrationDialog(Calibration::Type type = Calibration::Type::None);
|
||||
void UpdateCalWidget();
|
||||
|
||||
void createDefaultTracesAndGraphs(int ports);
|
||||
private slots:
|
||||
void EnableDeembedding(bool enable);
|
||||
void UpdateStatusbar();
|
||||
|
|
|
|||
|
|
@ -236,6 +236,11 @@ void AppWindow::SetupMenu()
|
|||
connect(ui->actionSource_Calibration, &QAction::triggered, this, &AppWindow::SourceCalibrationDialog);
|
||||
connect(ui->actionReceiver_Calibration, &QAction::triggered, this, &AppWindow::ReceiverCalibrationDialog);
|
||||
connect(ui->actionFrequency_Calibration, &QAction::triggered, this, &AppWindow::FrequencyCalibrationDialog);
|
||||
|
||||
connect(ui->actionPreset, &QAction::triggered, [=](){
|
||||
modeHandler->getActiveMode()->preset();
|
||||
});
|
||||
|
||||
connect(ui->actionPreferences, &QAction::triggered, [=](){
|
||||
// save previous SCPI settings in case they change
|
||||
auto &p = Preferences::getInstance();
|
||||
|
|
@ -338,6 +343,7 @@ bool AppWindow::ConnectToDevice(QString serial)
|
|||
ui->actionReceiver_Calibration->setEnabled(true);
|
||||
ui->actionFrequency_Calibration->setEnabled(true);
|
||||
}
|
||||
ui->actionPreset->setEnabled(true);
|
||||
|
||||
UpdateAcquisitionFrequencies();
|
||||
|
||||
|
|
@ -368,6 +374,7 @@ void AppWindow::DisconnectDevice()
|
|||
ui->actionSource_Calibration->setEnabled(false);
|
||||
ui->actionReceiver_Calibration->setEnabled(false);
|
||||
ui->actionFrequency_Calibration->setEnabled(false);
|
||||
ui->actionPreset->setEnabled(false);
|
||||
for(auto a : deviceActionGroup->actions()) {
|
||||
a->setChecked(false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,8 +82,15 @@
|
|||
</property>
|
||||
<addaction name="actionAbout"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuView">
|
||||
<property name="title">
|
||||
<string>View</string>
|
||||
</property>
|
||||
<addaction name="actionPreset"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuDevice"/>
|
||||
<addaction name="menuView"/>
|
||||
<addaction name="menuWindow"/>
|
||||
<addaction name="menuHelp"/>
|
||||
</widget>
|
||||
|
|
@ -209,6 +216,14 @@
|
|||
<string>Frequency Calibration</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPreset">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Preset</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="icons.qrc"/>
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ public:
|
|||
|
||||
virtual void setAveragingMode(Averaging::Mode mode) = 0;
|
||||
|
||||
virtual void preset() = 0;
|
||||
|
||||
signals:
|
||||
void statusbarMessage(QString msg);
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -138,6 +138,10 @@ PreferencesDialog::PreferencesDialog(Preferences *pref, QWidget *parent) :
|
|||
auto index = ui->compoundList->currentRow();
|
||||
if(index >= 0 && index < p->compoundDevices.size()) {
|
||||
auto d = new CompoundDeviceEditDialog(p->compoundDevices[index]);
|
||||
connect(d, &QDialog::accepted, [=](){
|
||||
ui->compoundList->item(index)->setText(p->compoundDevices[index]->getDesription());
|
||||
p->nonTrivialWriting();
|
||||
});
|
||||
d->show();
|
||||
}
|
||||
});
|
||||
|
|
@ -276,7 +280,7 @@ void PreferencesDialog::setInitialGUIState()
|
|||
ui->StartupSAAveraging->setValue(p->Startup.SA.averaging);
|
||||
ui->StartupSASignalID->setChecked(p->Startup.SA.signalID);
|
||||
|
||||
ui->AcquisitionAlwaysExciteBoth->setChecked(p->Acquisition.alwaysExciteBothPorts);
|
||||
ui->AcquisitionAlwaysExciteBoth->setChecked(p->Acquisition.alwaysExciteAllPorts);
|
||||
ui->AcquisitionSuppressPeaks->setChecked(p->Acquisition.suppressPeaks);
|
||||
ui->AcquisitionAdjustPowerLevel->setChecked(p->Acquisition.adjustPowerLevel);
|
||||
ui->AcquisitionUseHarmonic->setChecked(p->Acquisition.harmonicMixing);
|
||||
|
|
@ -346,7 +350,7 @@ void PreferencesDialog::updateFromGUI()
|
|||
p->Startup.SA.detector = ui->StartupSADetector->currentIndex();
|
||||
p->Startup.SA.signalID = ui->StartupSASignalID->isChecked();
|
||||
|
||||
p->Acquisition.alwaysExciteBothPorts = ui->AcquisitionAlwaysExciteBoth->isChecked();
|
||||
p->Acquisition.alwaysExciteAllPorts = ui->AcquisitionAlwaysExciteBoth->isChecked();
|
||||
p->Acquisition.suppressPeaks = ui->AcquisitionSuppressPeaks->isChecked();
|
||||
p->Acquisition.adjustPowerLevel = ui->AcquisitionAdjustPowerLevel->isChecked();
|
||||
p->Acquisition.harmonicMixing = ui->AcquisitionUseHarmonic->isChecked();
|
||||
|
|
@ -379,6 +383,8 @@ void PreferencesDialog::updateFromGUI()
|
|||
|
||||
p->SCPIServer.enabled = ui->SCPIServerEnabled->isChecked();
|
||||
p->SCPIServer.port = ui->SCPIServerPort->value();
|
||||
|
||||
p->nonTrivialWriting();
|
||||
}
|
||||
|
||||
void Preferences::load()
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ public:
|
|||
} SA;
|
||||
} Startup;
|
||||
struct {
|
||||
bool alwaysExciteBothPorts;
|
||||
bool alwaysExciteAllPorts;
|
||||
bool suppressPeaks;
|
||||
bool adjustPowerLevel;
|
||||
bool harmonicMixing;
|
||||
|
|
@ -145,7 +145,9 @@ public:
|
|||
|
||||
private:
|
||||
Preferences() :
|
||||
TCPoverride(false) {}
|
||||
TCPoverride(false) {
|
||||
qDebug() << "Pref constructor: " << &compoundDeviceJSON;
|
||||
}
|
||||
static Preferences instance;
|
||||
|
||||
const std::vector<Savable::SettingDescription> descr = {{
|
||||
|
|
@ -174,7 +176,7 @@ private:
|
|||
{&Startup.SA.detector, "Startup.SA.detector", 0},
|
||||
{&Startup.SA.averaging, "Startup.SA.averaging", 1},
|
||||
{&Startup.SA.signalID, "Startup.SA.signalID", true},
|
||||
{&Acquisition.alwaysExciteBothPorts, "Acquisition.alwaysExciteBothPorts", true},
|
||||
{&Acquisition.alwaysExciteAllPorts, "Acquisition.alwaysExciteBothPorts", true},
|
||||
{&Acquisition.suppressPeaks, "Acquisition.suppressPeaks", true},
|
||||
{&Acquisition.adjustPowerLevel, "Acquisition.adjustPowerLevel", false},
|
||||
{&Acquisition.harmonicMixing, "Acquisition.harmonicMixing", false},
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>687</width>
|
||||
<height>884</height>
|
||||
<height>938</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||
|
|
@ -103,7 +103,7 @@
|
|||
</size>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>5</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="Startup">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
|
|
@ -714,7 +714,7 @@
|
|||
<string><html><head/><body><p>If only S11/S21 or S22/S12 are enabled, faster sweeps are possible by only exciting one port. Checking this option forces the device to always excite both ports even when the measurements from one port will not be used.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Always perform full 2-port measurement</string>
|
||||
<string>Always create the stimulus signal at all ports</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
|||
|
|
@ -305,10 +305,6 @@ inline void App_Process() {
|
|||
}
|
||||
}
|
||||
if(HW::TimedOut()) {
|
||||
vTaskDelay(1000);
|
||||
LOG_WARN("Timed out, FPGA status: 0x%04x", FPGA::GetStatus());
|
||||
vTaskDelay(1000);
|
||||
LOG_WARN("Trigger out: %d (last reported: %d), in: %d", (uint8_t) Trigger::GetOutput(), (uint8_t) lastReportedTrigger, (uint8_t) Trigger::GetInput());
|
||||
HW::SetMode(HW::Mode::Idle);
|
||||
// insert the last received packet (restarts the timed out operation)
|
||||
Communication::BlockNextAck();
|
||||
|
|
|
|||
|
|
@ -130,7 +130,8 @@ using SweepSettings = struct _sweepSettings {
|
|||
uint16_t points;
|
||||
uint32_t if_bandwidth;
|
||||
int16_t cdbm_excitation_start; // in 1/100 dbm
|
||||
uint16_t unused:2;
|
||||
uint16_t unused:1;
|
||||
uint16_t syncMaster:1;
|
||||
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;
|
||||
|
|
@ -258,6 +259,7 @@ using SpectrumAnalyzerSettings = struct _spectrumAnalyzerSettings {
|
|||
* 3: Trigger synchronization (not supported yet by hardware)
|
||||
*/
|
||||
uint8_t syncMode :2;
|
||||
uint8_t syncMaster :1;
|
||||
int64_t trackingGeneratorOffset;
|
||||
int16_t trackingPower;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ 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 synchronize) {
|
||||
void FPGA::SetupSweep(uint8_t stages, uint8_t port1_stage, uint8_t port2_stage, bool synchronize, bool syncMaster) {
|
||||
uint16_t value = 0x0000;
|
||||
value |= (uint16_t) (stages & 0x07) << 13;
|
||||
if(synchronize) {
|
||||
|
|
@ -139,6 +139,7 @@ void FPGA::SetupSweep(uint8_t stages, uint8_t port1_stage, uint8_t port2_stage,
|
|||
value |= (port1_stage & 0x07) << 3;
|
||||
value |= (port2_stage & 0x07) << 0;
|
||||
WriteRegister(Reg::SweepSetup, value);
|
||||
Enable(Periphery::SyncMaster, syncMaster);
|
||||
}
|
||||
|
||||
void FPGA::Enable(Periphery p, bool enable) {
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ enum class Periphery {
|
|||
DebugLED = 0x0080,
|
||||
SourceChip = 0x0010,
|
||||
LO1Chip = 0x0008,
|
||||
|
||||
SyncMaster = 0x0002,
|
||||
PortSwitch = 0x0001,
|
||||
};
|
||||
|
||||
|
|
@ -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 synchronize = false);
|
||||
void SetupSweep(uint8_t stages, uint8_t port1_stage, uint8_t port2_stage, bool synchronize = false, bool syncMaster = false);
|
||||
void Enable(Periphery p, bool enable = true);
|
||||
void Disable(Periphery p);
|
||||
bool IsEnabled(Periphery p);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "delay.hpp"
|
||||
#include "SpectrumAnalyzer.hpp"
|
||||
#include "Communication.h"
|
||||
#include "Trigger.hpp"
|
||||
#include <cstring>
|
||||
|
||||
#define LOG_LEVEL LOG_LEVEL_INFO
|
||||
|
|
@ -230,6 +231,7 @@ bool HW::GetTemps(uint8_t *source, uint8_t *lo) {
|
|||
|
||||
void HW::SetIdle() {
|
||||
unlevel = false;
|
||||
Trigger::SetInput(false);
|
||||
FPGA::AbortSweep();
|
||||
FPGA::SetMode(FPGA::Mode::FPGA);
|
||||
FPGA::DisableHardwareOverwrite();
|
||||
|
|
|
|||
|
|
@ -87,8 +87,8 @@ void LED::Init() {
|
|||
#if HW_REVISION == 'B'
|
||||
led_ncnt = 0;
|
||||
mode = Mode::Off;
|
||||
HAL_TIM_Base_Start(&htim2);
|
||||
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
|
||||
// HAL_TIM_Base_Start(&htim2);
|
||||
// HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
|
||||
|
||||
LedStatusHandle = xTaskCreateStatic(LedStatus, "LedStatusTask", LED_STATUS_TASK_STACK_SIZE_WORDS,
|
||||
NULL, 6, LedStatusStack, &LedStatusCB);
|
||||
|
|
@ -132,3 +132,11 @@ void LED::Error(uint8_t code) {
|
|||
vTaskResume(LedStatusHandle);
|
||||
#endif
|
||||
}
|
||||
|
||||
void LED::On() {
|
||||
GPIOA->BSRR = GPIO_PIN_15;
|
||||
}
|
||||
|
||||
void LED::Toggle() {
|
||||
GPIOA->ODR ^= GPIO_PIN_15;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,4 +9,7 @@ void Pulsating();
|
|||
void Off();
|
||||
void Error(uint8_t code);
|
||||
|
||||
void On();
|
||||
void Toggle();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,7 +225,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, s.syncMode != 0);
|
||||
FPGA::SetupSweep(0, s.trackingGeneratorPort == 1, s.trackingGeneratorPort == 0, s.syncMode != 0, s.syncMaster);
|
||||
FPGA::Enable(FPGA::Periphery::PortSwitch, s.trackingGenerator);
|
||||
FPGA::Enable(FPGA::Periphery::Amplifier, s.trackingGenerator);
|
||||
FPGA::Enable(FPGA::Periphery::Port1Mixer);
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ bool VNA::Setup(Protocol::SweepSettings s) {
|
|||
FPGA::Enable(FPGA::Periphery::SourceRF);
|
||||
FPGA::Enable(FPGA::Periphery::LO1Chip);
|
||||
FPGA::Enable(FPGA::Periphery::LO1RF);
|
||||
FPGA::SetupSweep(s.stages, s.port1Stage, s.port2Stage, s.syncMode != 0);
|
||||
FPGA::SetupSweep(s.stages, s.port1Stage, s.port2Stage, s.syncMode != 0, s.syncMaster);
|
||||
Trigger::SetMode((Trigger::Mode) s.syncMode);
|
||||
FPGA::Enable(FPGA::Periphery::PortSwitch);
|
||||
pointCnt = 0;
|
||||
|
|
|
|||
|
|
@ -405,7 +405,7 @@ SPI2.VirtualType=VM_MASTER
|
|||
TIM1.IPParameters=Prescaler
|
||||
TIM1.Prescaler=159
|
||||
TIM2.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
|
||||
TIM2.IPParameters=Channel-PWM Generation1 CH1,Prescaler,PeriodNoDither,OCMode_PWM-PWM Generation1 CH1
|
||||
TIM2.IPParameters=Prescaler,PeriodNoDither,Channel-PWM Generation1 CH1,OCMode_PWM-PWM Generation1 CH1
|
||||
TIM2.OCMode_PWM-PWM\ Generation1\ CH1=TIM_OCMODE_PWM2
|
||||
TIM2.PeriodNoDither=99
|
||||
TIM2.Prescaler=143
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue