Skip to content

Commit

Permalink
Merge branch 'master' of github.com:jankae/LibreVNA
Browse files Browse the repository at this point in the history
  • Loading branch information
jankae committed Jul 24, 2023
2 parents d062028 + 94482fe commit 175cade
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 14 deletions.
Binary file modified Documentation/UserManual/ProgrammingGuide.pdf
Binary file not shown.
21 changes: 19 additions & 2 deletions Documentation/UserManual/ProgrammingGuide.tex
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,9 @@ \section{General Syntax}
\section{Commands}
\subsection{General Commands}
\subsubsection{*IDN}
\query{Returns the identifications string}{*IDN?}{None}{LibreVNA-GUI}
\query{Returns the identifications string}{*IDN?}{None}{LibreVNA,LibreVNA-GUI,dummy\_serial,<software version>}
\subsubsection{*OPC}
\query{Returns a 1 after every previous command has been handled}{*OPC?}{None}{1}
\subsubsection{*LST}
\query{Lists all available commands}{*LST?}{None}{List of commands, separated by newline}
\subsection{Device Commands}
Expand Down Expand Up @@ -249,6 +251,22 @@ \subsubsection{DEVice:MODE}
VNA
\end{example}

\subsubsection{DEVice:SETUP:SAVE}
\event{Saves the GUI setup to a file}{DEVice:SETUP:SAVE}{<filename>}
Important points when saving/loading setup files through SCPI commands:
\begin{itemize}
\item Filenames must be either absolute or relative to the location of the GUI application.
\item If the LibreVNA-GUI (and thus also the SCPI server) is running on a different machine than the SCPI client, the setup files will be saved/loaded from the machine that runs the GUI.
\item If no (or a wrong) file ending is specified, ``.setup'' is automatically added to the filename.
\end{itemize}

\subsubsection{DEVice:SETUP:LOAD}
\query{Loads a setup file}{DEVice:SETUP:LOAD?}{<filename>}{TRUE or FALSE}
\begin{itemize}
\item Filenames must be either absolute or relative to the location of the GUI application.
\item The filename must include the file ending ``.setup''.
\end{itemize}

\subsubsection{DEVice:REFerence:OUT}
\event{Sets the reference output frequency}{DEVice:REFerence:OUT <freq>}{<freq> in MHz, either 0 (disabled), 10 or 100}
\query{Queries the reference output frequency}{DEVice:REFerence:OUT?}{None}{Output frequency in MHz}
Expand Down Expand Up @@ -561,7 +579,6 @@ \subsubsection{VNA:CALibration:SAVE}
Important points when saving/loading calibration files through SCPI commands:
\begin{itemize}
\item Filenames must be either absolute or relative to the location of the GUI application.
\item SCPI parsing implicitly capitalizes all commands, the file will be saved using only uppercase letters. Similarly, it is not possible to load a file whose filename contains lowercase characters.
\item If the LibreVNA-GUI (and thus also the SCPI server) is running on a different machine than the SCPI client, the calibration files will be saved/loaded from the machine that runs the GUI.
\end{itemize}

Expand Down
50 changes: 50 additions & 0 deletions Documentation/UserManual/SCPI_Examples/deembedding_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env python3

import time
from libreVNA import libreVNA

# Create the control instance
vna = libreVNA('localhost', 19542)

# Quick connection check (should print "LibreVNA-GUI")
print(vna.query("*IDN?"))

vna.cmd(":VNA:DEEMB:CLEAR")
vna.cmd(":VNA:DEEMB:NEW PORT_EXTENSION")
vna.cmd(":VNA:DEEMB:NEW 2XTHRU")
vna.cmd(":VNA:DEEMB:NEW MATCHING_NETWORK")
vna.cmd(":VNA:DEEMB:NEW IMPEDANCE_RENORMALIZATION")

print("Number of total deembedding options:")
num_options = int(vna.query(":VNA:DEEMB:NUM?"))
print(num_options)

for i in range(1, num_options+1):
option_name = vna.query(":VNA:DEEMB:TYPE? "+str(i))
print("Option "+str(i)+": "+option_name)

# edit port extension
vna.cmd(":VNA:DEEMB:1:PORT 2")
vna.cmd(":VNA:DEEMB:1:DELAY 0.00002")
vna.cmd(":VNA:DEEMB:1:DCLOSS 1")
vna.cmd(":VNA:DEEMB:1:LOSS 3")
vna.cmd(":VNA:DEEMB:1:FREQUENCY 5000000000")

vna.cmd(":VNA:DEEMB:3:PORT 3")
vna.cmd(":VNA:DEEMB:3:CLEAR")
vna.cmd(":VNA:DEEMB:3:ADD FALSE")
vna.cmd(":VNA:DEEMB:3:NEW ParallelC")
vna.cmd(":VNA:DEEMB:3:NEW SeriesR")
vna.cmd(":VNA:DEEMB:3:NEW ParallelL")
vna.cmd(":VNA:DEEMB:3:NEW SeriesL")
vna.cmd(":VNA:DEEMB:3:NEW touchstone_shunt")

vna.cmd(":VNA:DEEMB:3:1:VALUE 0.0001")
vna.cmd(":VNA:DEEMB:3:2:VALUE 0.00002")
vna.cmd(":VNA:DEEMB:3:3:VALUE 0.000003")
vna.cmd(":VNA:DEEMB:3:4:VALUE 0.000004")

vna.cmd(":VNA:DEEMB:3:5:FILE TEST.S2P")

vna.cmd(":VNA:DEEMB:4:IMPedance 75")

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ using USBID = struct {
static constexpr USBID IDs[] = {
{0x0483, 0x564e},
{0x0483, 0x4121},
{0x1209, 0x4121},
};

USBInBuffer::USBInBuffer(libusb_device_handle *handle, unsigned char endpoint, int buffer_size) :
Expand Down
33 changes: 29 additions & 4 deletions Software/PC_Application/LibreVNA-GUI/appwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,10 @@ void AppWindow::CreateToolbars()
void AppWindow::SetupSCPI()
{
scpi.add(new SCPICommand("*IDN", nullptr, [=](QStringList){
return "LibreVNA-GUI";
return "LibreVNA,LibreVNA-GUI,dummy_serial,"+appVersion;
}));
scpi.add(new SCPICommand("*OPC", nullptr, [=](QStringList){
return "1";
}));
auto scpi_dev = new SCPINode("DEVice");
scpi.add(scpi_dev);
Expand Down Expand Up @@ -518,6 +521,27 @@ void AppWindow::SetupSCPI()
ret.chop(1);
return ret;
}));
auto scpi_setup = new SCPINode("SETUP");
scpi_dev->add(scpi_setup);
scpi_setup->add(new SCPICommand("SAVE", [=](QStringList params) -> QString {
if(params.size() != 1) {
// no filename given
return SCPI::getResultName(SCPI::Result::Error);
}
SaveSetup(params[0]);
return SCPI::getResultName(SCPI::Result::Empty);
}, nullptr, false));
scpi_setup->add(new SCPICommand("LOAD", nullptr, [=](QStringList params) -> QString {
if(params.size() != 1) {
// no filename given
return SCPI::getResultName(SCPI::Result::False);
}
if(!LoadSetup(params[0])) {
// some error when loading the setup file
return SCPI::getResultName(SCPI::Result::False);
}
return SCPI::getResultName(SCPI::Result::True);
}, false));
auto scpi_ref = new SCPINode("REFerence");
scpi_dev->add(scpi_ref);
scpi_ref->add(new SCPICommand("OUT", [=](QStringList params) -> QString {
Expand Down Expand Up @@ -1182,13 +1206,13 @@ nlohmann::json AppWindow::SaveSetup()
return j;
}

void AppWindow::LoadSetup(QString filename)
bool AppWindow::LoadSetup(QString filename)
{
ifstream file;
file.open(filename.toStdString());
if(!file.is_open()) {
qWarning() << "Unable to open file:" << filename;
return;
return false;
}
nlohmann::json j;
try {
Expand All @@ -1197,12 +1221,13 @@ void AppWindow::LoadSetup(QString filename)
InformationBox::ShowError("Error", "Failed to parse the setup file (" + QString(e.what()) + ")");
qWarning() << "Parsing of setup file failed: " << e.what();
file.close();
return;
return false;
}
file.close();
LoadSetup(j);
QFileInfo fi(filename);
lSetupName.setText("Setup: "+fi.fileName());
return true;
}

void AppWindow::LoadSetup(nlohmann::json j)
Expand Down
2 changes: 1 addition & 1 deletion Software/PC_Application/LibreVNA-GUI/appwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ private slots:
void DeviceFlagsUpdated();
void DeviceInfoUpdated();
void SaveSetup(QString filename);
void LoadSetup(QString filename);
bool LoadSetup(QString filename);
private:
nlohmann::json SaveSetup();
void LoadSetup(nlohmann::json j);
Expand Down
10 changes: 7 additions & 3 deletions Software/PC_Application/LibreVNA-GUI/scpi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ void SCPI::input(QString line)
if(cmd[0] == ':') {
cmd.remove(0, 1);
}
cmd = cmd.toUpper();
auto response = lastNode->parse(cmd, lastNode);
emit output(response);
}
Expand Down Expand Up @@ -274,7 +273,7 @@ QString SCPINode::parse(QString cmd, SCPINode* &lastNode)
// have not reached a leaf, find next subnode
auto subnode = cmd.left(splitPos);
for(auto n : subnodes) {
if(SCPI::match(n->name, subnode)) {
if(SCPI::match(n->name, subnode.toUpper())) {
// pass on to next level
return n->parse(cmd.right(cmd.size() - splitPos - 1), lastNode);
}
Expand All @@ -292,9 +291,14 @@ QString SCPINode::parse(QString cmd, SCPINode* &lastNode)
cmd.chop(1);
}
for(auto c : commands) {
if(SCPI::match(c->name(), cmd)) {
if(SCPI::match(c->name(), cmd.toUpper())) {
// save current node in case of non-root for the next command
lastNode = this;
if(c->convertToUppercase()) {
for(auto &p : params) {
p = p.toUpper();
}
}
if(isQuery) {
return c->query(params);
} else {
Expand Down
7 changes: 5 additions & 2 deletions Software/PC_Application/LibreVNA-GUI/scpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,23 @@

class SCPICommand {
public:
SCPICommand(QString name, std::function<QString(QStringList)> cmd, std::function<QString(QStringList)> query) :
SCPICommand(QString name, std::function<QString(QStringList)> cmd, std::function<QString(QStringList)> query, bool convertToUppercase = true) :
_name(name),
fn_cmd(cmd),
fn_query(query){}
fn_query(query),
argAlwaysUppercase(convertToUppercase){}

QString execute(QStringList params);
QString query(QStringList params);
QString name() {return _name;}
bool queryable() { return fn_query != nullptr;}
bool executable() { return fn_cmd != nullptr;}
bool convertToUppercase() { return argAlwaysUppercase;}
private:
const QString _name;
std::function<QString(QStringList)> fn_cmd;
std::function<QString(QStringList)> fn_query;
bool argAlwaysUppercase;
};

class SCPINode {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@
* @{
*/

#define USBD_VID 0x0483
#define USBD_VID 0x1209
#define USBD_PID_FS 0x4121
#define USBD_LANGID_STRING 0x0409
#define USBD_MANUFACTURER_STRING "STMicroelectronics"
#define USBD_MANUFACTURER_STRING "LibreVNA"
#define USBD_PRODUCT_STRING_FS "VNA"
#define USBD_CONFIGURATION_STRING_FS "CustomUSBDevice Config"
#define USBD_INTERFACE_STRING_FS "CustomUSBDevice Interface"
Expand Down

0 comments on commit 175cade

Please sign in to comment.