Protocol adjustment + exposing settings for DFT
This commit is contained in:
parent
ce475fa042
commit
a2389fca13
@ -111,22 +111,40 @@ uint8_t *USBInBuffer::getBuffer() const
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Protocol::DeviceLimits limits = {
|
static constexpr Protocol::DeviceInfo defaultInfo = {
|
||||||
.minFreq = 0,
|
.ProtocolVersion = Protocol::Version,
|
||||||
.maxFreq = 6000000000,
|
.FW_major = 0,
|
||||||
.minIFBW = 10,
|
.FW_minor = 0,
|
||||||
.maxIFBW = 50000,
|
.FW_patch = 0,
|
||||||
.maxPoints = 4501,
|
.HW_Revision = '0',
|
||||||
.cdbm_min = -4000,
|
.extRefAvailable = 0,
|
||||||
.cdbm_max = 0,
|
.extRefInUse = 0,
|
||||||
.minRBW = 10,
|
.FPGA_configured = 0,
|
||||||
.maxRBW = 100000,
|
.source_locked = 0,
|
||||||
|
.LO1_locked = 0,
|
||||||
|
.ADC_overload = 0,
|
||||||
|
.temp_source = 0,
|
||||||
|
.temp_LO1 = 0,
|
||||||
|
.temp_MCU = 0,
|
||||||
|
.limits_minFreq = 0,
|
||||||
|
.limits_maxFreq = 6000000000,
|
||||||
|
.limits_minIFBW = 10,
|
||||||
|
.limits_maxIFBW = 50000,
|
||||||
|
.limits_maxPoints = 4501,
|
||||||
|
.limits_cdbm_min = -4000,
|
||||||
|
.limits_cdbm_max = 0,
|
||||||
|
.limits_minRBW = 15,
|
||||||
|
.limits_maxRBW = 100000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Protocol::DeviceInfo Device::lastInfo = defaultInfo;
|
||||||
|
|
||||||
Device::Device(QString serial)
|
Device::Device(QString serial)
|
||||||
{
|
{
|
||||||
qDebug() << "Starting device connection...";
|
qDebug() << "Starting device connection...";
|
||||||
|
|
||||||
|
lastInfo = defaultInfo;
|
||||||
|
|
||||||
m_handle = nullptr;
|
m_handle = nullptr;
|
||||||
lastInfoValid = false;
|
lastInfoValid = false;
|
||||||
libusb_init(&m_context);
|
libusb_init(&m_context);
|
||||||
@ -182,8 +200,8 @@ Device::Device(QString serial)
|
|||||||
connect(this, &Device::receivedAnswer, this, &Device::transmissionFinished, Qt::QueuedConnection);
|
connect(this, &Device::receivedAnswer, this, &Device::transmissionFinished, Qt::QueuedConnection);
|
||||||
transmissionTimer.setSingleShot(true);
|
transmissionTimer.setSingleShot(true);
|
||||||
transmissionActive = false;
|
transmissionActive = false;
|
||||||
// got a new connection, request limits
|
// got a new connection, request info
|
||||||
SendCommandWithoutPayload(Protocol::PacketType::RequestDeviceLimits);
|
SendCommandWithoutPayload(Protocol::PacketType::RequestDeviceInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
Device::~Device()
|
Device::~Device()
|
||||||
@ -282,11 +300,6 @@ std::set<QString> Device::GetDevices()
|
|||||||
return serials;
|
return serials;
|
||||||
}
|
}
|
||||||
|
|
||||||
Protocol::DeviceLimits Device::Limits()
|
|
||||||
{
|
|
||||||
return limits;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Device::USBHandleThread()
|
void Device::USBHandleThread()
|
||||||
{
|
{
|
||||||
qInfo() << "Receive thread started" << flush;
|
qInfo() << "Receive thread started" << flush;
|
||||||
@ -366,7 +379,7 @@ void Device::SearchDevices(std::function<bool (libusb_device_handle *, QString)>
|
|||||||
libusb_free_device_list(devList, 1);
|
libusb_free_device_list(devList, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Protocol::DeviceInfo Device::getLastInfo() const
|
const Protocol::DeviceInfo &Device::Info()
|
||||||
{
|
{
|
||||||
return lastInfo;
|
return lastInfo;
|
||||||
}
|
}
|
||||||
@ -379,8 +392,8 @@ QString Device::getLastDeviceInfoString()
|
|||||||
} else {
|
} else {
|
||||||
ret.append("HW Rev.");
|
ret.append("HW Rev.");
|
||||||
ret.append(lastInfo.HW_Revision);
|
ret.append(lastInfo.HW_Revision);
|
||||||
ret.append(" FW "+QString::number(lastInfo.FW_major)+"."+QString::number(lastInfo.FW_minor).rightJustified(2, '0'));
|
ret.append(" FW "+QString::number(lastInfo.FW_major)+"."+QString::number(lastInfo.FW_minor)+"."+QString::number(lastInfo.FW_patch));
|
||||||
ret.append(" Temps: "+QString::number(lastInfo.temperatures.source)+"°C/"+QString::number(lastInfo.temperatures.LO1)+"°C/"+QString::number(lastInfo.temperatures.MCU)+"°C");
|
ret.append(" Temps: "+QString::number(lastInfo.temp_source)+"°C/"+QString::number(lastInfo.temp_LO1)+"°C/"+QString::number(lastInfo.temp_MCU)+"°C");
|
||||||
ret.append(" Reference:");
|
ret.append(" Reference:");
|
||||||
if(lastInfo.extRefInUse) {
|
if(lastInfo.extRefInUse) {
|
||||||
ret.append("External");
|
ret.append("External");
|
||||||
@ -412,7 +425,13 @@ void Device::ReceivedData()
|
|||||||
emit SpectrumResultReceived(packet.spectrumResult);
|
emit SpectrumResultReceived(packet.spectrumResult);
|
||||||
break;
|
break;
|
||||||
case Protocol::PacketType::DeviceInfo:
|
case Protocol::PacketType::DeviceInfo:
|
||||||
|
if(packet.info.ProtocolVersion != Protocol::Version) {
|
||||||
|
if(!lastInfoValid) {
|
||||||
|
emit NeedsFirmwareUpdate(packet.info.ProtocolVersion, Protocol::Version);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
lastInfo = packet.info;
|
lastInfo = packet.info;
|
||||||
|
}
|
||||||
lastInfoValid = true;
|
lastInfoValid = true;
|
||||||
emit DeviceInfoUpdated();
|
emit DeviceInfoUpdated();
|
||||||
break;
|
break;
|
||||||
@ -424,9 +443,6 @@ void Device::ReceivedData()
|
|||||||
emit NackReceived();
|
emit NackReceived();
|
||||||
emit receivedAnswer(TransmissionResult::Nack);
|
emit receivedAnswer(TransmissionResult::Nack);
|
||||||
break;
|
break;
|
||||||
case Protocol::PacketType::DeviceLimits:
|
|
||||||
limits = packet.limits;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -65,12 +65,11 @@ public:
|
|||||||
bool SendFirmwareChunk(Protocol::FirmwarePacket &fw);
|
bool SendFirmwareChunk(Protocol::FirmwarePacket &fw);
|
||||||
bool SendCommandWithoutPayload(Protocol::PacketType type);
|
bool SendCommandWithoutPayload(Protocol::PacketType type);
|
||||||
QString serial() const;
|
QString serial() const;
|
||||||
Protocol::DeviceInfo getLastInfo() const;
|
static const Protocol::DeviceInfo& Info();
|
||||||
QString getLastDeviceInfoString();
|
QString getLastDeviceInfoString();
|
||||||
|
|
||||||
// Returns serial numbers of all connected devices
|
// Returns serial numbers of all connected devices
|
||||||
static std::set<QString> GetDevices();
|
static std::set<QString> GetDevices();
|
||||||
static Protocol::DeviceLimits Limits();
|
|
||||||
signals:
|
signals:
|
||||||
void DatapointReceived(Protocol::Datapoint);
|
void DatapointReceived(Protocol::Datapoint);
|
||||||
void ManualStatusReceived(Protocol::ManualStatus);
|
void ManualStatusReceived(Protocol::ManualStatus);
|
||||||
@ -80,6 +79,7 @@ signals:
|
|||||||
void AckReceived();
|
void AckReceived();
|
||||||
void NackReceived();
|
void NackReceived();
|
||||||
void LogLineReceived(QString line);
|
void LogLineReceived(QString line);
|
||||||
|
void NeedsFirmwareUpdate(int usedProtocol, int requiredProtocol);
|
||||||
private slots:
|
private slots:
|
||||||
void ReceivedData();
|
void ReceivedData();
|
||||||
void ReceivedLog();
|
void ReceivedLog();
|
||||||
@ -119,7 +119,7 @@ private:
|
|||||||
QString m_serial;
|
QString m_serial;
|
||||||
bool m_connected;
|
bool m_connected;
|
||||||
std::thread *m_receiveThread;
|
std::thread *m_receiveThread;
|
||||||
Protocol::DeviceInfo lastInfo;
|
static Protocol::DeviceInfo lastInfo;
|
||||||
bool lastInfoValid;
|
bool lastInfoValid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,10 +10,10 @@ SignalgeneratorWidget::SignalgeneratorWidget(QWidget *parent) :
|
|||||||
ui->frequency->setPrefixes(" kMG");
|
ui->frequency->setPrefixes(" kMG");
|
||||||
|
|
||||||
connect(ui->frequency, &SIUnitEdit::valueChanged, [=](double newval) {
|
connect(ui->frequency, &SIUnitEdit::valueChanged, [=](double newval) {
|
||||||
if(newval < Device::Limits().minFreq) {
|
if(newval < Device::Info().limits_minFreq) {
|
||||||
newval = Device::Limits().minFreq;
|
newval = Device::Info().limits_minFreq;
|
||||||
} else if (newval > Device::Limits().maxFreq) {
|
} else if (newval > Device::Info().limits_maxFreq) {
|
||||||
newval = Device::Limits().maxFreq;
|
newval = Device::Info().limits_maxFreq;
|
||||||
}
|
}
|
||||||
ui->frequency->setValueQuiet(newval);
|
ui->frequency->setValueQuiet(newval);
|
||||||
emit SettingsChanged();
|
emit SettingsChanged();
|
||||||
|
@ -251,6 +251,13 @@ void SpectrumAnalyzer::SettingsChanged()
|
|||||||
settings.pointNum = settings.f_stop - settings.f_start + 1;
|
settings.pointNum = settings.f_stop - settings.f_start + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto pref = Preferences::getInstance();
|
||||||
|
if(pref.Acquisition.useDFTinSAmode && settings.RBW <= pref.Acquisition.RBWLimitForDFT) {
|
||||||
|
settings.UseDFT = 1;
|
||||||
|
} else {
|
||||||
|
settings.UseDFT = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(window->getDevice()) {
|
if(window->getDevice()) {
|
||||||
window->getDevice()->Configure(settings);
|
window->getDevice()->Configure(settings);
|
||||||
}
|
}
|
||||||
@ -311,8 +318,8 @@ void SpectrumAnalyzer::SetSpan(double span)
|
|||||||
|
|
||||||
void SpectrumAnalyzer::SetFullSpan()
|
void SpectrumAnalyzer::SetFullSpan()
|
||||||
{
|
{
|
||||||
settings.f_start = Device::Limits().minFreq;
|
settings.f_start = Device::Info().limits_minFreq;
|
||||||
settings.f_stop = Device::Limits().maxFreq;
|
settings.f_stop = Device::Info().limits_maxFreq;
|
||||||
ConstrainAndUpdateFrequencies();
|
ConstrainAndUpdateFrequencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,10 +347,10 @@ void SpectrumAnalyzer::SpanZoomOut()
|
|||||||
|
|
||||||
void SpectrumAnalyzer::SetRBW(double bandwidth)
|
void SpectrumAnalyzer::SetRBW(double bandwidth)
|
||||||
{
|
{
|
||||||
if(bandwidth > Device::Limits().maxRBW) {
|
if(bandwidth > Device::Info().limits_maxRBW) {
|
||||||
bandwidth = Device::Limits().maxRBW;
|
bandwidth = Device::Info().limits_maxRBW;
|
||||||
} else if(bandwidth < Device::Limits().minRBW) {
|
} else if(bandwidth < Device::Info().limits_minRBW) {
|
||||||
bandwidth = Device::Limits().minRBW;
|
bandwidth = Device::Info().limits_minRBW;
|
||||||
}
|
}
|
||||||
settings.RBW = bandwidth;
|
settings.RBW = bandwidth;
|
||||||
emit RBWChanged(settings.RBW);
|
emit RBWChanged(settings.RBW);
|
||||||
@ -365,14 +372,14 @@ void SpectrumAnalyzer::UpdateAverageCount()
|
|||||||
|
|
||||||
void SpectrumAnalyzer::ConstrainAndUpdateFrequencies()
|
void SpectrumAnalyzer::ConstrainAndUpdateFrequencies()
|
||||||
{
|
{
|
||||||
if(settings.f_stop > Device::Limits().maxFreq) {
|
if(settings.f_stop > Device::Info().limits_maxFreq) {
|
||||||
settings.f_stop = Device::Limits().maxFreq;
|
settings.f_stop = Device::Info().limits_maxFreq;
|
||||||
}
|
}
|
||||||
if(settings.f_start > settings.f_stop) {
|
if(settings.f_start > settings.f_stop) {
|
||||||
settings.f_start = settings.f_stop;
|
settings.f_start = settings.f_stop;
|
||||||
}
|
}
|
||||||
if(settings.f_start < Device::Limits().minFreq) {
|
if(settings.f_start < Device::Info().limits_minFreq) {
|
||||||
settings.f_start = Device::Limits().minFreq;
|
settings.f_start = Device::Info().limits_minFreq;
|
||||||
}
|
}
|
||||||
emit startFreqChanged(settings.f_start);
|
emit startFreqChanged(settings.f_start);
|
||||||
emit stopFreqChanged(settings.f_stop);
|
emit stopFreqChanged(settings.f_stop);
|
||||||
|
@ -217,7 +217,11 @@ VNA::VNA(AppWindow *window)
|
|||||||
points->setSingleStep(100);
|
points->setSingleStep(100);
|
||||||
points->setToolTip("Points/sweep");
|
points->setToolTip("Points/sweep");
|
||||||
connect(points, qOverload<int>(&QSpinBox::valueChanged), this, &VNA::SetPoints);
|
connect(points, qOverload<int>(&QSpinBox::valueChanged), this, &VNA::SetPoints);
|
||||||
connect(this, &VNA::pointsChanged, points, &QSpinBox::setValue);
|
connect(this, &VNA::pointsChanged, [=](int p) {
|
||||||
|
points->blockSignals(true);
|
||||||
|
points->setValue(p);
|
||||||
|
points->blockSignals(false);
|
||||||
|
});
|
||||||
tb_acq->addWidget(new QLabel("Points:"));
|
tb_acq->addWidget(new QLabel("Points:"));
|
||||||
tb_acq->addWidget(points);
|
tb_acq->addWidget(points);
|
||||||
|
|
||||||
@ -499,8 +503,8 @@ void VNA::SetSpan(double span)
|
|||||||
|
|
||||||
void VNA::SetFullSpan()
|
void VNA::SetFullSpan()
|
||||||
{
|
{
|
||||||
settings.f_start = Device::Limits().minFreq;
|
settings.f_start = Device::Info().limits_minFreq;
|
||||||
settings.f_stop = Device::Limits().maxFreq;
|
settings.f_stop = Device::Info().limits_maxFreq;
|
||||||
ConstrainAndUpdateFrequencies();
|
ConstrainAndUpdateFrequencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,10 +532,10 @@ void VNA::SpanZoomOut()
|
|||||||
|
|
||||||
void VNA::SetSourceLevel(double level)
|
void VNA::SetSourceLevel(double level)
|
||||||
{
|
{
|
||||||
if(level > Device::Limits().cdbm_max / 100.0) {
|
if(level > Device::Info().limits_cdbm_max / 100.0) {
|
||||||
level = Device::Limits().cdbm_max / 100.0;
|
level = Device::Info().limits_cdbm_max / 100.0;
|
||||||
} else if(level < Device::Limits().cdbm_min / 100.0) {
|
} else if(level < Device::Info().limits_cdbm_min / 100.0) {
|
||||||
level = Device::Limits().cdbm_min / 100.0;
|
level = Device::Info().limits_cdbm_min / 100.0;
|
||||||
}
|
}
|
||||||
emit sourceLevelChanged(level);
|
emit sourceLevelChanged(level);
|
||||||
settings.cdbm_excitation = level * 100;
|
settings.cdbm_excitation = level * 100;
|
||||||
@ -540,10 +544,10 @@ void VNA::SetSourceLevel(double level)
|
|||||||
|
|
||||||
void VNA::SetPoints(unsigned int points)
|
void VNA::SetPoints(unsigned int points)
|
||||||
{
|
{
|
||||||
if (points < 2) {
|
if(points > Device::Info().limits_maxPoints) {
|
||||||
|
points = Device::Info().limits_maxPoints;
|
||||||
|
} else if (points < 2) {
|
||||||
points = 2;
|
points = 2;
|
||||||
} else if(points > Device::Limits().maxPoints) {
|
|
||||||
points = Device::Limits().maxPoints;
|
|
||||||
}
|
}
|
||||||
emit pointsChanged(points);
|
emit pointsChanged(points);
|
||||||
settings.points = points;
|
settings.points = points;
|
||||||
@ -552,10 +556,10 @@ void VNA::SetPoints(unsigned int points)
|
|||||||
|
|
||||||
void VNA::SetIFBandwidth(double bandwidth)
|
void VNA::SetIFBandwidth(double bandwidth)
|
||||||
{
|
{
|
||||||
if(bandwidth > Device::Limits().maxIFBW) {
|
if(bandwidth > Device::Info().limits_maxIFBW) {
|
||||||
bandwidth = Device::Limits().maxIFBW;
|
bandwidth = Device::Info().limits_maxIFBW;
|
||||||
} else if(bandwidth < Device::Limits().minIFBW) {
|
} else if(bandwidth < Device::Info().limits_minIFBW) {
|
||||||
bandwidth = Device::Limits().minIFBW;
|
bandwidth = Device::Info().limits_minIFBW;
|
||||||
}
|
}
|
||||||
settings.if_bandwidth = bandwidth;
|
settings.if_bandwidth = bandwidth;
|
||||||
emit IFBandwidthChanged(bandwidth);
|
emit IFBandwidthChanged(bandwidth);
|
||||||
@ -651,14 +655,14 @@ void VNA::StartCalibrationMeasurement(Calibration::Measurement m)
|
|||||||
|
|
||||||
void VNA::ConstrainAndUpdateFrequencies()
|
void VNA::ConstrainAndUpdateFrequencies()
|
||||||
{
|
{
|
||||||
if(settings.f_stop > Device::Limits().maxFreq) {
|
if(settings.f_stop > Device::Info().limits_maxFreq) {
|
||||||
settings.f_stop = Device::Limits().maxFreq;
|
settings.f_stop = Device::Info().limits_maxFreq;
|
||||||
}
|
}
|
||||||
if(settings.f_start > settings.f_stop) {
|
if(settings.f_start > settings.f_stop) {
|
||||||
settings.f_start = settings.f_stop;
|
settings.f_start = settings.f_stop;
|
||||||
}
|
}
|
||||||
if(settings.f_start < Device::Limits().minFreq) {
|
if(settings.f_start < Device::Info().limits_minFreq) {
|
||||||
settings.f_start = Device::Limits().minFreq;
|
settings.f_start = Device::Info().limits_minFreq;
|
||||||
}
|
}
|
||||||
emit startFreqChanged(settings.f_start);
|
emit startFreqChanged(settings.f_start);
|
||||||
emit stopFreqChanged(settings.f_stop);
|
emit stopFreqChanged(settings.f_stop);
|
||||||
|
@ -95,14 +95,7 @@ AppWindow::AppWindow(QWidget *parent)
|
|||||||
connect(ui->actionDisconnect, &QAction::triggered, this, &AppWindow::DisconnectDevice);
|
connect(ui->actionDisconnect, &QAction::triggered, this, &AppWindow::DisconnectDevice);
|
||||||
connect(ui->actionQuit, &QAction::triggered, this, &AppWindow::close);
|
connect(ui->actionQuit, &QAction::triggered, this, &AppWindow::close);
|
||||||
connect(ui->actionManual_Control, &QAction::triggered, this, &AppWindow::StartManualControl);
|
connect(ui->actionManual_Control, &QAction::triggered, this, &AppWindow::StartManualControl);
|
||||||
connect(ui->actionFirmware_Update, &QAction::triggered, [=](){
|
connect(ui->actionFirmware_Update, &QAction::triggered, this, &AppWindow::StartFirmwareUpdateDialog);
|
||||||
if(device) {
|
|
||||||
auto fw_update = new FirmwareUpdateDialog(device);
|
|
||||||
connect(fw_update, &FirmwareUpdateDialog::DeviceRebooting, this, &AppWindow::DisconnectDevice);
|
|
||||||
connect(fw_update, &FirmwareUpdateDialog::DeviceRebooted, this, &AppWindow::ConnectToDevice);
|
|
||||||
fw_update->exec();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
connect(ui->actionPreferences, &QAction::triggered, [=](){
|
connect(ui->actionPreferences, &QAction::triggered, [=](){
|
||||||
Preferences::getInstance().edit();
|
Preferences::getInstance().edit();
|
||||||
// settings might have changed, update necessary stuff
|
// settings might have changed, update necessary stuff
|
||||||
@ -172,6 +165,7 @@ void AppWindow::ConnectToDevice(QString serial)
|
|||||||
connect(device, &Device::DeviceInfoUpdated, [this]() {
|
connect(device, &Device::DeviceInfoUpdated, [this]() {
|
||||||
lDeviceInfo.setText(device->getLastDeviceInfoString());
|
lDeviceInfo.setText(device->getLastDeviceInfoString());
|
||||||
});
|
});
|
||||||
|
connect(device, &Device::NeedsFirmwareUpdate, this, &AppWindow::DeviceNeedsUpdate);
|
||||||
ui->actionDisconnect->setEnabled(true);
|
ui->actionDisconnect->setEnabled(true);
|
||||||
ui->actionManual_Control->setEnabled(true);
|
ui->actionManual_Control->setEnabled(true);
|
||||||
ui->actionFirmware_Update->setEnabled(true);
|
ui->actionFirmware_Update->setEnabled(true);
|
||||||
@ -316,6 +310,28 @@ void AppWindow::UpdateReference()
|
|||||||
device->SendPacket(p);
|
device->SendPacket(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AppWindow::StartFirmwareUpdateDialog()
|
||||||
|
{
|
||||||
|
if(device) {
|
||||||
|
auto fw_update = new FirmwareUpdateDialog(device);
|
||||||
|
connect(fw_update, &FirmwareUpdateDialog::DeviceRebooting, this, &AppWindow::DisconnectDevice);
|
||||||
|
connect(fw_update, &FirmwareUpdateDialog::DeviceRebooted, this, &AppWindow::ConnectToDevice);
|
||||||
|
fw_update->exec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppWindow::DeviceNeedsUpdate(int reported, int expected)
|
||||||
|
{
|
||||||
|
auto ret = QMessageBox::warning(this, "Warning",
|
||||||
|
"The device reports are different protocol"
|
||||||
|
"version (" + QString::number(reported) + ") than expected (" + QString::number(expected) + ").\n"
|
||||||
|
"A firmware update is strongly suggested. Do you want to update now?",
|
||||||
|
QMessageBox::Yes | QMessageBox::No);
|
||||||
|
if (ret == QMessageBox::Yes) {
|
||||||
|
StartFirmwareUpdateDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Device *AppWindow::getDevice() const
|
Device *AppWindow::getDevice() const
|
||||||
{
|
{
|
||||||
return device;
|
return device;
|
||||||
|
@ -42,7 +42,8 @@ private slots:
|
|||||||
int UpdateDeviceList();
|
int UpdateDeviceList();
|
||||||
void StartManualControl();
|
void StartManualControl();
|
||||||
void UpdateReference();
|
void UpdateReference();
|
||||||
|
void StartFirmwareUpdateDialog();
|
||||||
|
void DeviceNeedsUpdate(int reported, int expected);
|
||||||
private:
|
private:
|
||||||
void DeviceConnectionLost();
|
void DeviceConnectionLost();
|
||||||
void CreateToolbars();
|
void CreateToolbars();
|
||||||
|
@ -67,6 +67,13 @@ PreferencesDialog::PreferencesDialog(Preferences *pref, QWidget *parent) :
|
|||||||
ui->StartupSARBW->setUnit("Hz");
|
ui->StartupSARBW->setUnit("Hz");
|
||||||
ui->StartupSARBW->setPrefixes(" k");
|
ui->StartupSARBW->setPrefixes(" k");
|
||||||
|
|
||||||
|
// Acquisition page
|
||||||
|
ui->AcquisitionDFTlimitRBW->setUnit("Hz");
|
||||||
|
ui->AcquisitionDFTlimitRBW->setPrefixes(" k");
|
||||||
|
connect(ui->AcquisitionUseDFT, &QCheckBox::toggled, [=](bool enabled) {
|
||||||
|
ui->AcquisitionDFTlimitRBW->setEnabled(enabled);
|
||||||
|
});
|
||||||
|
|
||||||
// Page selection
|
// Page selection
|
||||||
connect(ui->treeWidget, &QTreeWidget::currentItemChanged, [=](QTreeWidgetItem *current, QTreeWidgetItem *) {
|
connect(ui->treeWidget, &QTreeWidget::currentItemChanged, [=](QTreeWidgetItem *current, QTreeWidgetItem *) {
|
||||||
auto name = current->text(0);
|
auto name = current->text(0);
|
||||||
@ -107,6 +114,8 @@ PreferencesDialog::PreferencesDialog(Preferences *pref, QWidget *parent) :
|
|||||||
p->Startup.SA.signalID = ui->StartupSASignalID->isChecked();
|
p->Startup.SA.signalID = ui->StartupSASignalID->isChecked();
|
||||||
p->Acquisition.alwaysExciteBothPorts = ui->AcquisitionAlwaysExciteBoth->isChecked();
|
p->Acquisition.alwaysExciteBothPorts = ui->AcquisitionAlwaysExciteBoth->isChecked();
|
||||||
p->Acquisition.suppressPeaks = ui->AcquisitionSuppressPeaks->isChecked();
|
p->Acquisition.suppressPeaks = ui->AcquisitionSuppressPeaks->isChecked();
|
||||||
|
p->Acquisition.useDFTinSAmode = ui->AcquisitionUseDFT->isChecked();
|
||||||
|
p->Acquisition.RBWLimitForDFT = ui->AcquisitionDFTlimitRBW->value();
|
||||||
p->General.graphColors.background = ui->GeneralGraphBackground->getColor();
|
p->General.graphColors.background = ui->GeneralGraphBackground->getColor();
|
||||||
p->General.graphColors.axis = ui->GeneralGraphAxis->getColor();
|
p->General.graphColors.axis = ui->GeneralGraphAxis->getColor();
|
||||||
p->General.graphColors.divisions = ui->GeneralGraphDivisions->getColor();
|
p->General.graphColors.divisions = ui->GeneralGraphDivisions->getColor();
|
||||||
@ -147,6 +156,8 @@ void PreferencesDialog::setInitialGUIState()
|
|||||||
|
|
||||||
ui->AcquisitionAlwaysExciteBoth->setChecked(p->Acquisition.alwaysExciteBothPorts);
|
ui->AcquisitionAlwaysExciteBoth->setChecked(p->Acquisition.alwaysExciteBothPorts);
|
||||||
ui->AcquisitionSuppressPeaks->setChecked(p->Acquisition.suppressPeaks);
|
ui->AcquisitionSuppressPeaks->setChecked(p->Acquisition.suppressPeaks);
|
||||||
|
ui->AcquisitionUseDFT->setChecked(p->Acquisition.useDFTinSAmode);
|
||||||
|
ui->AcquisitionDFTlimitRBW->setValue(p->Acquisition.RBWLimitForDFT);
|
||||||
|
|
||||||
ui->GeneralGraphBackground->setColor(p->General.graphColors.background);
|
ui->GeneralGraphBackground->setColor(p->General.graphColors.background);
|
||||||
ui->GeneralGraphAxis->setColor(p->General.graphColors.axis);
|
ui->GeneralGraphAxis->setColor(p->General.graphColors.axis);
|
||||||
|
@ -44,6 +44,8 @@ public:
|
|||||||
struct {
|
struct {
|
||||||
bool alwaysExciteBothPorts;
|
bool alwaysExciteBothPorts;
|
||||||
bool suppressPeaks;
|
bool suppressPeaks;
|
||||||
|
bool useDFTinSAmode;
|
||||||
|
double RBWLimitForDFT;
|
||||||
} Acquisition;
|
} Acquisition;
|
||||||
struct {
|
struct {
|
||||||
struct {
|
struct {
|
||||||
@ -60,7 +62,7 @@ private:
|
|||||||
QString name;
|
QString name;
|
||||||
QVariant def;
|
QVariant def;
|
||||||
};
|
};
|
||||||
const std::array<SettingDescription, 22> descr = {{
|
const std::array<SettingDescription, 24> descr = {{
|
||||||
{&Startup.ConnectToFirstDevice, "Startup.ConnectToFirstDevice", true},
|
{&Startup.ConnectToFirstDevice, "Startup.ConnectToFirstDevice", true},
|
||||||
{&Startup.RememberSweepSettings, "Startup.RememberSweepSettings", false},
|
{&Startup.RememberSweepSettings, "Startup.RememberSweepSettings", false},
|
||||||
{&Startup.DefaultSweep.start, "Startup.DefaultSweep.start", 1000000.0},
|
{&Startup.DefaultSweep.start, "Startup.DefaultSweep.start", 1000000.0},
|
||||||
@ -80,6 +82,8 @@ private:
|
|||||||
{&Startup.SA.signalID, "Startup.SA.signalID", true},
|
{&Startup.SA.signalID, "Startup.SA.signalID", true},
|
||||||
{&Acquisition.alwaysExciteBothPorts, "Acquisition.alwaysExciteBothPorts", true},
|
{&Acquisition.alwaysExciteBothPorts, "Acquisition.alwaysExciteBothPorts", true},
|
||||||
{&Acquisition.suppressPeaks, "Acquisition.suppressPeaks", true},
|
{&Acquisition.suppressPeaks, "Acquisition.suppressPeaks", true},
|
||||||
|
{&Acquisition.useDFTinSAmode, "Acquisition.useDFTinSAmode", true},
|
||||||
|
{&Acquisition.RBWLimitForDFT, "Acquisition.RBWLimitForDFT", 3000.0},
|
||||||
{&General.graphColors.background, "General.graphColors.background", QColor(Qt::black)},
|
{&General.graphColors.background, "General.graphColors.background", QColor(Qt::black)},
|
||||||
{&General.graphColors.axis, "General.graphColors.axis", QColor(Qt::white)},
|
{&General.graphColors.axis, "General.graphColors.axis", QColor(Qt::white)},
|
||||||
{&General.graphColors.divisions, "General.graphColors.divisions", QColor(Qt::gray)},
|
{&General.graphColors.divisions, "General.graphColors.divisions", QColor(Qt::gray)},
|
||||||
|
@ -73,7 +73,7 @@
|
|||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="Startup">
|
<widget class="QWidget" name="Startup">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
@ -453,6 +453,12 @@
|
|||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="Acquisition">
|
<widget class="QWidget" name="Acquisition">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_6">
|
||||||
|
<property name="title">
|
||||||
|
<string>Vector Network Analyzer</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="AcquisitionAlwaysExciteBoth">
|
<widget class="QCheckBox" name="AcquisitionAlwaysExciteBoth">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
@ -473,6 +479,35 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_7">
|
||||||
|
<property name="title">
|
||||||
|
<string>Spectrum Analyzer</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||||
|
<item>
|
||||||
|
<layout class="QFormLayout" name="formLayout_5">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QCheckBox" name="AcquisitionUseDFT">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Normally, the spectrum analyzer mode tunes the LO for each point and measures the final IF only at one frequency. When this option is enabled, a DFT of the final IF is calculated instead which covers multiple frequencies with one measurement.</p><p>This can speed up the measurement at low RBWs significantly.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Use DFT when RBW is below</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="SIUnitEdit" name="AcquisitionDFTlimitRBW"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer_2">
|
<spacer name="verticalSpacer_2">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
@ -189,6 +189,8 @@
|
|||||||
|
|
||||||
<listOptionValue builtIn="false" value="FW_MAJOR=0"/>
|
<listOptionValue builtIn="false" value="FW_MAJOR=0"/>
|
||||||
|
|
||||||
|
<listOptionValue builtIn="false" value="FW_PATCH=0"/>
|
||||||
|
|
||||||
<listOptionValue builtIn="false" value="FW_MINOR=1"/>
|
<listOptionValue builtIn="false" value="FW_MINOR=1"/>
|
||||||
|
|
||||||
<listOptionValue builtIn="false" value="USE_FULL_LL_DRIVER"/>
|
<listOptionValue builtIn="false" value="USE_FULL_LL_DRIVER"/>
|
||||||
|
@ -155,10 +155,10 @@ void App_Start() {
|
|||||||
SA::Setup(recv_packet.spectrumSettings);
|
SA::Setup(recv_packet.spectrumSettings);
|
||||||
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
|
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
|
||||||
break;
|
break;
|
||||||
case Protocol::PacketType::RequestDeviceLimits:
|
case Protocol::PacketType::RequestDeviceInfo:
|
||||||
Protocol::PacketInfo p;
|
Protocol::PacketInfo p;
|
||||||
p.type = Protocol::PacketType::DeviceLimits;
|
p.type = Protocol::PacketType::DeviceInfo;
|
||||||
p.limits = HW::Limits;
|
HW::fillDeviceInfo(&p.info);
|
||||||
Communication::Send(p);
|
Communication::Send(p);
|
||||||
break;
|
break;
|
||||||
#ifdef HAS_FLASH
|
#ifdef HAS_FLASH
|
||||||
|
@ -238,35 +238,58 @@ static int16_t EncodeGeneratorSettings(Protocol::GeneratorSettings d, uint8_t *b
|
|||||||
static Protocol::DeviceInfo DecodeDeviceInfo(uint8_t *buf) {
|
static Protocol::DeviceInfo DecodeDeviceInfo(uint8_t *buf) {
|
||||||
Protocol::DeviceInfo d;
|
Protocol::DeviceInfo d;
|
||||||
Decoder e(buf);
|
Decoder e(buf);
|
||||||
e.get<uint16_t>(d.FW_major);
|
e.get(d.ProtocolVersion);
|
||||||
e.get<uint16_t>(d.FW_minor);
|
e.get(d.FW_major);
|
||||||
e.get<char>(d.HW_Revision);
|
e.get(d.FW_minor);
|
||||||
|
e.get(d.FW_patch);
|
||||||
|
e.get(d.HW_Revision);
|
||||||
d.extRefAvailable = e.getBits(1);
|
d.extRefAvailable = e.getBits(1);
|
||||||
d.extRefInUse = e.getBits(1);
|
d.extRefInUse = e.getBits(1);
|
||||||
d.FPGA_configured = e.getBits(1);
|
d.FPGA_configured = e.getBits(1);
|
||||||
d.source_locked = e.getBits(1);
|
d.source_locked = e.getBits(1);
|
||||||
d.LO1_locked = e.getBits(1);
|
d.LO1_locked = e.getBits(1);
|
||||||
d.ADC_overload = e.getBits(1);
|
d.ADC_overload = e.getBits(1);
|
||||||
e.get<uint8_t>(d.temperatures.source);
|
e.get(d.temp_source);
|
||||||
e.get<uint8_t>(d.temperatures.LO1);
|
e.get(d.temp_LO1);
|
||||||
e.get<uint8_t>(d.temperatures.MCU);
|
e.get(d.temp_MCU);
|
||||||
|
e.get(d.limits_minFreq);
|
||||||
|
e.get(d.limits_maxFreq);
|
||||||
|
e.get(d.limits_minIFBW);
|
||||||
|
e.get(d.limits_maxIFBW);
|
||||||
|
e.get(d.limits_maxPoints);
|
||||||
|
e.get(d.limits_cdbm_min);
|
||||||
|
e.get(d.limits_cdbm_max);
|
||||||
|
e.get(d.limits_minRBW);
|
||||||
|
e.get(d.limits_maxRBW);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
static int16_t EncodeDeviceInfo(Protocol::DeviceInfo d, uint8_t *buf,
|
static int16_t EncodeDeviceInfo(Protocol::DeviceInfo d, uint8_t *buf,
|
||||||
uint16_t bufSize) {
|
uint16_t bufSize) {
|
||||||
|
d.ProtocolVersion = Protocol::Version;
|
||||||
Encoder e(buf, bufSize);
|
Encoder e(buf, bufSize);
|
||||||
e.add<uint16_t>(d.FW_major);
|
e.add(d.ProtocolVersion);
|
||||||
e.add<uint16_t>(d.FW_minor);
|
e.add(d.FW_major);
|
||||||
e.add<char>(d.HW_Revision);
|
e.add(d.FW_minor);
|
||||||
|
e.add(d.FW_patch);
|
||||||
|
e.add(d.HW_Revision);
|
||||||
e.addBits(d.extRefAvailable, 1);
|
e.addBits(d.extRefAvailable, 1);
|
||||||
e.addBits(d.extRefInUse, 1);
|
e.addBits(d.extRefInUse, 1);
|
||||||
e.addBits(d.FPGA_configured, 1);
|
e.addBits(d.FPGA_configured, 1);
|
||||||
e.addBits(d.source_locked, 1);
|
e.addBits(d.source_locked, 1);
|
||||||
e.addBits(d.LO1_locked, 1);
|
e.addBits(d.LO1_locked, 1);
|
||||||
e.addBits(d.ADC_overload, 1);
|
e.addBits(d.ADC_overload, 1);
|
||||||
e.add<uint8_t>(d.temperatures.source);
|
e.add(d.temp_source);
|
||||||
e.add<uint8_t>(d.temperatures.LO1);
|
e.add(d.temp_LO1);
|
||||||
e.add<uint8_t>(d.temperatures.MCU);
|
e.add(d.temp_MCU);
|
||||||
|
e.add(d.limits_minFreq);
|
||||||
|
e.add(d.limits_maxFreq);
|
||||||
|
e.add(d.limits_minIFBW);
|
||||||
|
e.add(d.limits_maxIFBW);
|
||||||
|
e.add(d.limits_maxPoints);
|
||||||
|
e.add(d.limits_cdbm_min);
|
||||||
|
e.add(d.limits_cdbm_max);
|
||||||
|
e.add(d.limits_minRBW);
|
||||||
|
e.add(d.limits_maxRBW);
|
||||||
return e.getSize();
|
return e.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,6 +401,7 @@ static Protocol::SpectrumAnalyzerSettings DecodeSpectrumAnalyzerSettings(uint8_t
|
|||||||
d.WindowType = e.getBits(2);
|
d.WindowType = e.getBits(2);
|
||||||
d.SignalID = e.getBits(1);
|
d.SignalID = e.getBits(1);
|
||||||
d.Detector = e.getBits(3);
|
d.Detector = e.getBits(3);
|
||||||
|
d.UseDFT = e.getBits(1);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
static int16_t EncodeSpectrumAnalyzerSettings(Protocol::SpectrumAnalyzerSettings d, uint8_t *buf,
|
static int16_t EncodeSpectrumAnalyzerSettings(Protocol::SpectrumAnalyzerSettings d, uint8_t *buf,
|
||||||
@ -390,6 +414,7 @@ static int16_t EncodeSpectrumAnalyzerSettings(Protocol::SpectrumAnalyzerSettings
|
|||||||
e.addBits(d.WindowType, 2);
|
e.addBits(d.WindowType, 2);
|
||||||
e.addBits(d.SignalID, 1);
|
e.addBits(d.SignalID, 1);
|
||||||
e.addBits(d.Detector, 3);
|
e.addBits(d.Detector, 3);
|
||||||
|
e.addBits(d.UseDFT, 1);
|
||||||
return e.getSize();
|
return e.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,35 +437,6 @@ static int16_t EncodeSpectrumAnalyzerResult(Protocol::SpectrumAnalyzerResult d,
|
|||||||
return e.getSize();
|
return e.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Protocol::DeviceLimits DecodeDeviceLimits(uint8_t *buf) {
|
|
||||||
Protocol::DeviceLimits d;
|
|
||||||
Decoder e(buf);
|
|
||||||
e.get(d.minFreq);
|
|
||||||
e.get(d.maxFreq);
|
|
||||||
e.get(d.minIFBW);
|
|
||||||
e.get(d.maxIFBW);
|
|
||||||
e.get(d.maxPoints);
|
|
||||||
e.get(d.cdbm_min);
|
|
||||||
e.get(d.cdbm_max);
|
|
||||||
e.get(d.minRBW);
|
|
||||||
e.get(d.maxRBW);
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
static int16_t EncodeDeviceLimits(Protocol::DeviceLimits d, uint8_t *buf,
|
|
||||||
uint16_t bufSize) {
|
|
||||||
Encoder e(buf, bufSize);
|
|
||||||
e.add(d.minFreq);
|
|
||||||
e.add(d.maxFreq);
|
|
||||||
e.add(d.minIFBW);
|
|
||||||
e.add(d.maxIFBW);
|
|
||||||
e.add(d.maxPoints);
|
|
||||||
e.add(d.cdbm_min);
|
|
||||||
e.add(d.cdbm_max);
|
|
||||||
e.add(d.minRBW);
|
|
||||||
e.add(d.maxRBW);
|
|
||||||
return e.getSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
static Protocol::FirmwarePacket DecodeFirmwarePacket(uint8_t *buf) {
|
static Protocol::FirmwarePacket DecodeFirmwarePacket(uint8_t *buf) {
|
||||||
Protocol::FirmwarePacket d;
|
Protocol::FirmwarePacket d;
|
||||||
// simple packet format, memcpy is faster than using the decoder
|
// simple packet format, memcpy is faster than using the decoder
|
||||||
@ -545,14 +541,11 @@ uint16_t Protocol::DecodeBuffer(uint8_t *buf, uint16_t len, PacketInfo *info) {
|
|||||||
case PacketType::SpectrumAnalyzerResult:
|
case PacketType::SpectrumAnalyzerResult:
|
||||||
info->spectrumResult = DecodeSpectrumAnalyzerResult(&data[4]);
|
info->spectrumResult = DecodeSpectrumAnalyzerResult(&data[4]);
|
||||||
break;
|
break;
|
||||||
case PacketType::DeviceLimits:
|
|
||||||
info->limits = DecodeDeviceLimits(&data[4]);
|
|
||||||
break;
|
|
||||||
case PacketType::Ack:
|
case PacketType::Ack:
|
||||||
case PacketType::PerformFirmwareUpdate:
|
case PacketType::PerformFirmwareUpdate:
|
||||||
case PacketType::ClearFlash:
|
case PacketType::ClearFlash:
|
||||||
case PacketType::Nack:
|
case PacketType::Nack:
|
||||||
case PacketType::RequestDeviceLimits:
|
case PacketType::RequestDeviceInfo:
|
||||||
// no payload, nothing to do
|
// no payload, nothing to do
|
||||||
break;
|
break;
|
||||||
case PacketType::None:
|
case PacketType::None:
|
||||||
@ -595,14 +588,11 @@ uint16_t Protocol::EncodePacket(const PacketInfo &packet, uint8_t *dest, uint16_
|
|||||||
case PacketType::SpectrumAnalyzerResult:
|
case PacketType::SpectrumAnalyzerResult:
|
||||||
payload_size = EncodeSpectrumAnalyzerResult(packet.spectrumResult, &dest[4], destsize - 8);
|
payload_size = EncodeSpectrumAnalyzerResult(packet.spectrumResult, &dest[4], destsize - 8);
|
||||||
break;
|
break;
|
||||||
case PacketType::DeviceLimits:
|
|
||||||
payload_size = EncodeDeviceLimits(packet.limits, &dest[4], destsize - 8);
|
|
||||||
break;
|
|
||||||
case PacketType::Ack:
|
case PacketType::Ack:
|
||||||
case PacketType::PerformFirmwareUpdate:
|
case PacketType::PerformFirmwareUpdate:
|
||||||
case PacketType::ClearFlash:
|
case PacketType::ClearFlash:
|
||||||
case PacketType::Nack:
|
case PacketType::Nack:
|
||||||
case PacketType::RequestDeviceLimits:
|
case PacketType::RequestDeviceInfo:
|
||||||
// no payload, nothing to do
|
// no payload, nothing to do
|
||||||
break;
|
break;
|
||||||
case PacketType::None:
|
case PacketType::None:
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
namespace Protocol {
|
namespace Protocol {
|
||||||
|
|
||||||
|
static constexpr uint16_t Version = 1;
|
||||||
|
|
||||||
// When changing/adding/removing variables from these structs also adjust the decode/encode functions in Protocol.cpp
|
// When changing/adding/removing variables from these structs also adjust the decode/encode functions in Protocol.cpp
|
||||||
|
|
||||||
using Datapoint = struct _datapoint {
|
using Datapoint = struct _datapoint {
|
||||||
@ -39,8 +41,10 @@ using GeneratorSettings = struct _generatorSettings {
|
|||||||
};
|
};
|
||||||
|
|
||||||
using DeviceInfo = struct _deviceInfo {
|
using DeviceInfo = struct _deviceInfo {
|
||||||
uint16_t FW_major;
|
uint16_t ProtocolVersion;
|
||||||
uint16_t FW_minor;
|
uint8_t FW_major;
|
||||||
|
uint8_t FW_minor;
|
||||||
|
uint8_t FW_patch;
|
||||||
char HW_Revision;
|
char HW_Revision;
|
||||||
uint8_t extRefAvailable:1;
|
uint8_t extRefAvailable:1;
|
||||||
uint8_t extRefInUse:1;
|
uint8_t extRefInUse:1;
|
||||||
@ -48,11 +52,18 @@ using DeviceInfo = struct _deviceInfo {
|
|||||||
uint8_t source_locked:1;
|
uint8_t source_locked:1;
|
||||||
uint8_t LO1_locked:1;
|
uint8_t LO1_locked:1;
|
||||||
uint8_t ADC_overload:1;
|
uint8_t ADC_overload:1;
|
||||||
struct {
|
uint8_t temp_source;
|
||||||
uint8_t source;
|
uint8_t temp_LO1;
|
||||||
uint8_t LO1;
|
uint8_t temp_MCU;
|
||||||
uint8_t MCU;
|
uint64_t limits_minFreq;
|
||||||
} temperatures;
|
uint64_t limits_maxFreq;
|
||||||
|
uint32_t limits_minIFBW;
|
||||||
|
uint32_t limits_maxIFBW;
|
||||||
|
uint16_t limits_maxPoints;
|
||||||
|
int16_t limits_cdbm_min;
|
||||||
|
int16_t limits_cdbm_max;
|
||||||
|
uint32_t limits_minRBW;
|
||||||
|
uint32_t limits_maxRBW;
|
||||||
};
|
};
|
||||||
|
|
||||||
using ManualStatus = struct _manualstatus {
|
using ManualStatus = struct _manualstatus {
|
||||||
@ -107,6 +118,7 @@ using SpectrumAnalyzerSettings = struct _spectrumAnalyzerSettings {
|
|||||||
uint8_t WindowType :2;
|
uint8_t WindowType :2;
|
||||||
uint8_t SignalID :1;
|
uint8_t SignalID :1;
|
||||||
uint8_t Detector :3;
|
uint8_t Detector :3;
|
||||||
|
uint8_t UseDFT :1;
|
||||||
};
|
};
|
||||||
|
|
||||||
using SpectrumAnalyzerResult = struct _spectrumAnalyzerResult {
|
using SpectrumAnalyzerResult = struct _spectrumAnalyzerResult {
|
||||||
@ -116,18 +128,6 @@ using SpectrumAnalyzerResult = struct _spectrumAnalyzerResult {
|
|||||||
uint16_t pointNum;
|
uint16_t pointNum;
|
||||||
};
|
};
|
||||||
|
|
||||||
using DeviceLimits = struct _deviceLimits {
|
|
||||||
uint64_t minFreq;
|
|
||||||
uint64_t maxFreq;
|
|
||||||
uint32_t minIFBW;
|
|
||||||
uint32_t maxIFBW;
|
|
||||||
uint16_t maxPoints;
|
|
||||||
int16_t cdbm_min;
|
|
||||||
int16_t cdbm_max;
|
|
||||||
uint32_t minRBW;
|
|
||||||
uint32_t maxRBW;
|
|
||||||
};
|
|
||||||
|
|
||||||
static constexpr uint16_t FirmwareChunkSize = 256;
|
static constexpr uint16_t FirmwareChunkSize = 256;
|
||||||
using FirmwarePacket = struct _firmwarePacket {
|
using FirmwarePacket = struct _firmwarePacket {
|
||||||
uint32_t address;
|
uint32_t address;
|
||||||
@ -150,8 +150,7 @@ enum class PacketType : uint8_t {
|
|||||||
Generator = 12,
|
Generator = 12,
|
||||||
SpectrumAnalyzerSettings = 13,
|
SpectrumAnalyzerSettings = 13,
|
||||||
SpectrumAnalyzerResult = 14,
|
SpectrumAnalyzerResult = 14,
|
||||||
RequestDeviceLimits = 15,
|
RequestDeviceInfo = 15,
|
||||||
DeviceLimits = 16,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using PacketInfo = struct _packetinfo {
|
using PacketInfo = struct _packetinfo {
|
||||||
@ -167,7 +166,6 @@ using PacketInfo = struct _packetinfo {
|
|||||||
ManualStatus status;
|
ManualStatus status;
|
||||||
SpectrumAnalyzerSettings spectrumSettings;
|
SpectrumAnalyzerSettings spectrumSettings;
|
||||||
SpectrumAnalyzerResult spectrumResult;
|
SpectrumAnalyzerResult spectrumResult;
|
||||||
DeviceLimits limits;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "VNA.hpp"
|
#include "VNA.hpp"
|
||||||
#include "Manual.hpp"
|
#include "Manual.hpp"
|
||||||
#include "SpectrumAnalyzer.hpp"
|
#include "SpectrumAnalyzer.hpp"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#define LOG_LEVEL LOG_LEVEL_INFO
|
#define LOG_LEVEL LOG_LEVEL_INFO
|
||||||
#define LOG_MODULE "HW"
|
#define LOG_MODULE "HW"
|
||||||
@ -222,7 +223,12 @@ void HW::SetIdle() {
|
|||||||
FPGA::Enable(FPGA::Periphery::PortSwitch, false);
|
FPGA::Enable(FPGA::Periphery::PortSwitch, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HW::fillDeviceInfo(Protocol::DeviceInfo *info) {
|
void HW::fillDeviceInfo(Protocol::DeviceInfo *info, bool updateEvenWhenBusy) {
|
||||||
|
// copy constant default values
|
||||||
|
memcpy(info, &HW::Info, sizeof(HW::Info));
|
||||||
|
if(activeMode == Mode::Idle || updateEvenWhenBusy) {
|
||||||
|
// updating values from FPGA allowed
|
||||||
|
|
||||||
// read PLL temperatures
|
// read PLL temperatures
|
||||||
uint8_t tempSource, tempLO;
|
uint8_t tempSource, tempLO;
|
||||||
GetTemps(&tempSource, &tempLO);
|
GetTemps(&tempSource, &tempLO);
|
||||||
@ -232,7 +238,7 @@ void HW::fillDeviceInfo(Protocol::DeviceInfo *info) {
|
|||||||
LOG_INFO("ADC limits: P1: %d/%d P2: %d/%d R: %d/%d",
|
LOG_INFO("ADC limits: P1: %d/%d P2: %d/%d R: %d/%d",
|
||||||
limits.P1min, limits.P1max, limits.P2min, limits.P2max,
|
limits.P1min, limits.P1max, limits.P2min, limits.P2max,
|
||||||
limits.Rmin, limits.Rmax);
|
limits.Rmin, limits.Rmax);
|
||||||
#define ADC_LIMIT 30000
|
#define ADC_LIMIT 30000
|
||||||
if(limits.P1min < -ADC_LIMIT || limits.P1max > ADC_LIMIT
|
if(limits.P1min < -ADC_LIMIT || limits.P1max > ADC_LIMIT
|
||||||
|| limits.P2min < -ADC_LIMIT || limits.P2max > ADC_LIMIT
|
|| limits.P2min < -ADC_LIMIT || limits.P2max > ADC_LIMIT
|
||||||
|| limits.Rmin < -ADC_LIMIT || limits.Rmax > ADC_LIMIT) {
|
|| limits.Rmin < -ADC_LIMIT || limits.Rmax > ADC_LIMIT) {
|
||||||
@ -245,10 +251,11 @@ void HW::fillDeviceInfo(Protocol::DeviceInfo *info) {
|
|||||||
info->source_locked = (status & (int) FPGA::Interrupt::SourceUnlock) ? 0 : 1;
|
info->source_locked = (status & (int) FPGA::Interrupt::SourceUnlock) ? 0 : 1;
|
||||||
info->extRefAvailable = Ref::available();
|
info->extRefAvailable = Ref::available();
|
||||||
info->extRefInUse = extRefInUse;
|
info->extRefInUse = extRefInUse;
|
||||||
info->temperatures.LO1 = tempLO;
|
info->temp_LO1 = tempLO;
|
||||||
info->temperatures.source = tempSource;
|
info->temp_source = tempSource;
|
||||||
info->temperatures.MCU = STM::getTemperature();
|
|
||||||
FPGA::ResetADCLimits();
|
FPGA::ResetADCLimits();
|
||||||
|
}
|
||||||
|
info->temp_MCU = STM::getTemperature();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HW::Ref::available() {
|
bool HW::Ref::available() {
|
||||||
|
@ -38,16 +38,30 @@ static_assert(ADCprescaler * ADCSamplerate == FPGA::Clockrate, "ADCSamplerate ca
|
|||||||
static constexpr uint16_t DFTphaseInc = 4096 * IF2 / ADCSamplerate;
|
static constexpr uint16_t DFTphaseInc = 4096 * IF2 / ADCSamplerate;
|
||||||
static_assert(DFTphaseInc * ADCSamplerate == 4096 * IF2, "DFT can not be computed for 2.IF");
|
static_assert(DFTphaseInc * ADCSamplerate == 4096 * IF2, "DFT can not be computed for 2.IF");
|
||||||
|
|
||||||
static constexpr Protocol::DeviceLimits Limits = {
|
static constexpr Protocol::DeviceInfo Info = {
|
||||||
.minFreq = 0,
|
.ProtocolVersion = Protocol::Version,
|
||||||
.maxFreq = 6000000000,
|
.FW_major = FW_MAJOR,
|
||||||
.minIFBW = ADCSamplerate / MaxSamples,
|
.FW_minor = FW_MINOR,
|
||||||
.maxIFBW = ADCSamplerate / MinSamples,
|
.FW_patch = FW_PATCH,
|
||||||
.maxPoints = FPGA::MaxPoints,
|
.HW_Revision = HW_REVISION,
|
||||||
.cdbm_min = -4000,
|
.extRefAvailable = 0,
|
||||||
.cdbm_max = 0,
|
.extRefInUse = 0,
|
||||||
.minRBW = (uint32_t) (ADCSamplerate * 2.23f / MaxSamples),
|
.FPGA_configured = 0,
|
||||||
.maxRBW = (uint32_t) (ADCSamplerate * 2.23f / MinSamples),
|
.source_locked = 0,
|
||||||
|
.LO1_locked = 0,
|
||||||
|
.ADC_overload = 0,
|
||||||
|
.temp_source = 0,
|
||||||
|
.temp_LO1 = 0,
|
||||||
|
.temp_MCU = 0,
|
||||||
|
.limits_minFreq = 0,
|
||||||
|
.limits_maxFreq = 6000000000,
|
||||||
|
.limits_minIFBW = ADCSamplerate / MaxSamples,
|
||||||
|
.limits_maxIFBW = ADCSamplerate / MinSamples,
|
||||||
|
.limits_maxPoints = FPGA::MaxPoints,
|
||||||
|
.limits_cdbm_min = -4000,
|
||||||
|
.limits_cdbm_max = 0,
|
||||||
|
.limits_minRBW = (uint32_t) (ADCSamplerate * 2.23f / MaxSamples),
|
||||||
|
.limits_maxRBW = (uint32_t) (ADCSamplerate * 2.23f / MinSamples),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Mode {
|
enum class Mode {
|
||||||
@ -63,7 +77,7 @@ void SetIdle();
|
|||||||
void Work();
|
void Work();
|
||||||
|
|
||||||
bool GetTemps(uint8_t *source, uint8_t *lo);
|
bool GetTemps(uint8_t *source, uint8_t *lo);
|
||||||
void fillDeviceInfo(Protocol::DeviceInfo *info);
|
void fillDeviceInfo(Protocol::DeviceInfo *info, bool updateEvenWhenBusy = false);
|
||||||
namespace Ref {
|
namespace Ref {
|
||||||
bool available();
|
bool available();
|
||||||
// reference won't change until update is called
|
// reference won't change until update is called
|
||||||
|
@ -23,7 +23,6 @@ static Protocol::PacketInfo p;
|
|||||||
static bool active = false;
|
static bool active = false;
|
||||||
static uint32_t lastLO2;
|
static uint32_t lastLO2;
|
||||||
static uint32_t actualRBW;
|
static uint32_t actualRBW;
|
||||||
static bool usingDFT;
|
|
||||||
static uint16_t DFTpoints;
|
static uint16_t DFTpoints;
|
||||||
static bool negativeDFT; // if true, a positive frequency shift at input results in a negative shift at the 2.IF. Handle DFT accordingly
|
static bool negativeDFT; // if true, a positive frequency shift at input results in a negative shift at the 2.IF. Handle DFT accordingly
|
||||||
|
|
||||||
@ -106,7 +105,7 @@ static void StartNextSample() {
|
|||||||
Si5351.SetCLK(SiChannel::Port2LO2, LO2freq, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
|
Si5351.SetCLK(SiChannel::Port2LO2, LO2freq, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
|
||||||
lastLO2 = LO2freq;
|
lastLO2 = LO2freq;
|
||||||
}
|
}
|
||||||
if (usingDFT) {
|
if (s.UseDFT) {
|
||||||
uint32_t spacing = (s.f_stop - s.f_start) / (points - 1);
|
uint32_t spacing = (s.f_stop - s.f_start) / (points - 1);
|
||||||
uint32_t start = HW::IF2;
|
uint32_t start = HW::IF2;
|
||||||
if(negativeDFT) {
|
if(negativeDFT) {
|
||||||
@ -166,11 +165,16 @@ void SA::Setup(Protocol::SpectrumAnalyzerSettings settings) {
|
|||||||
FPGA::Enable(FPGA::Periphery::Port1Mixer);
|
FPGA::Enable(FPGA::Periphery::Port1Mixer);
|
||||||
FPGA::Enable(FPGA::Periphery::Port2Mixer);
|
FPGA::Enable(FPGA::Periphery::Port2Mixer);
|
||||||
|
|
||||||
// automatically select DFT mode for lower RBWs
|
if (s.UseDFT) {
|
||||||
usingDFT = actualRBW <= 1000;
|
uint32_t spacing = (s.f_stop - s.f_start) / (points - 1);
|
||||||
|
// The DFT can only look at a small bandwidth otherwise the passband of the final ADC filter is visible in the data
|
||||||
if (usingDFT) {
|
// Limit to about 30kHz
|
||||||
DFTpoints = FPGA::DFTbins; // use full DFT in FPGA
|
uint32_t maxDFTpoints = 30000 / spacing;
|
||||||
|
// Limit to actual supported number of bins
|
||||||
|
if(maxDFTpoints > FPGA::DFTbins) {
|
||||||
|
maxDFTpoints = FPGA::DFTbins;
|
||||||
|
}
|
||||||
|
DFTpoints = maxDFTpoints;
|
||||||
FPGA::DisableInterrupt(FPGA::Interrupt::NewData);
|
FPGA::DisableInterrupt(FPGA::Interrupt::NewData);
|
||||||
} else {
|
} else {
|
||||||
DFTpoints = 1; // can only measure one point at a time
|
DFTpoints = 1; // can only measure one point at a time
|
||||||
@ -191,7 +195,7 @@ bool SA::MeasurementDone(const FPGA::SamplingResult &result) {
|
|||||||
|
|
||||||
for(uint16_t i=0;i<DFTpoints;i++) {
|
for(uint16_t i=0;i<DFTpoints;i++) {
|
||||||
float port1, port2;
|
float port1, port2;
|
||||||
if (usingDFT) {
|
if (s.UseDFT) {
|
||||||
// use DFT result
|
// use DFT result
|
||||||
auto dft = FPGA::ReadDFTResult();
|
auto dft = FPGA::ReadDFTResult();
|
||||||
port1 = dft.P1;
|
port1 = dft.P1;
|
||||||
@ -217,7 +221,7 @@ bool SA::MeasurementDone(const FPGA::SamplingResult &result) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usingDFT) {
|
if (s.UseDFT) {
|
||||||
FPGA::StopDFT();
|
FPGA::StopDFT();
|
||||||
// will be started again in StartNextSample
|
// will be started again in StartNextSample
|
||||||
}
|
}
|
||||||
|
@ -264,9 +264,8 @@ void VNA::Work() {
|
|||||||
packet.info.FW_major = FW_MAJOR;
|
packet.info.FW_major = FW_MAJOR;
|
||||||
packet.info.FW_minor = FW_MINOR;
|
packet.info.FW_minor = FW_MINOR;
|
||||||
packet.info.HW_Revision = HW_REVISION;
|
packet.info.HW_Revision = HW_REVISION;
|
||||||
HW::fillDeviceInfo(&packet.info);
|
HW::fillDeviceInfo(&packet.info, true);
|
||||||
Communication::Send(packet);
|
Communication::Send(packet);
|
||||||
FPGA::ResetADCLimits();
|
|
||||||
// Start next sweep
|
// Start next sweep
|
||||||
FPGA::StartSweep();
|
FPGA::StartSweep();
|
||||||
}
|
}
|
||||||
|
@ -101,6 +101,7 @@ MCU = $(CPU) -mthumb $(FLOAT-ABI) $(FPU)
|
|||||||
C_DEFS = \
|
C_DEFS = \
|
||||||
-DFW_MAJOR=0 \
|
-DFW_MAJOR=0 \
|
||||||
-DFW_MINOR=1 \
|
-DFW_MINOR=1 \
|
||||||
|
-DFW_PATCH=0 \
|
||||||
-DUSE_FULL_LL_DRIVER \
|
-DUSE_FULL_LL_DRIVER \
|
||||||
-DHW_REVISION="'B'" \
|
-DHW_REVISION="'B'" \
|
||||||
-D__weak="__attribute__((weak))" \
|
-D__weak="__attribute__((weak))" \
|
||||||
|
Loading…
Reference in New Issue
Block a user