2022-10-01 17:10:44 +02:00
|
|
|
|
#ifndef SCPI_H
|
|
|
|
|
|
#define SCPI_H
|
|
|
|
|
|
|
|
|
|
|
|
#include <QString>
|
|
|
|
|
|
#include <QObject>
|
2024-12-02 14:02:34 +01:00
|
|
|
|
#include <QSemaphore>
|
2022-10-01 17:10:44 +02:00
|
|
|
|
#include <vector>
|
|
|
|
|
|
#include <functional>
|
|
|
|
|
|
|
|
|
|
|
|
class SCPICommand {
|
|
|
|
|
|
public:
|
2023-07-21 13:43:38 +02:00
|
|
|
|
SCPICommand(QString name, std::function<QString(QStringList)> cmd, std::function<QString(QStringList)> query, bool convertToUppercase = true) :
|
2022-10-01 17:10:44 +02:00
|
|
|
|
_name(name),
|
|
|
|
|
|
fn_cmd(cmd),
|
2023-07-21 13:43:38 +02:00
|
|
|
|
fn_query(query),
|
|
|
|
|
|
argAlwaysUppercase(convertToUppercase){}
|
2022-10-01 17:10:44 +02:00
|
|
|
|
|
|
|
|
|
|
QString execute(QStringList params);
|
|
|
|
|
|
QString query(QStringList params);
|
|
|
|
|
|
QString name() {return _name;}
|
|
|
|
|
|
bool queryable() { return fn_query != nullptr;}
|
|
|
|
|
|
bool executable() { return fn_cmd != nullptr;}
|
2023-07-21 13:43:38 +02:00
|
|
|
|
bool convertToUppercase() { return argAlwaysUppercase;}
|
2024-12-15 17:40:19 +01:00
|
|
|
|
QString leafName() {return _name.split(":").back();}
|
2022-10-01 17:10:44 +02:00
|
|
|
|
private:
|
|
|
|
|
|
const QString _name;
|
|
|
|
|
|
std::function<QString(QStringList)> fn_cmd;
|
|
|
|
|
|
std::function<QString(QStringList)> fn_query;
|
2023-07-21 13:43:38 +02:00
|
|
|
|
bool argAlwaysUppercase;
|
2022-10-01 17:10:44 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class SCPINode {
|
|
|
|
|
|
friend class SCPI;
|
|
|
|
|
|
public:
|
|
|
|
|
|
SCPINode(QString name) :
|
2024-04-07 14:11:04 +02:00
|
|
|
|
name(name), parent(nullptr), operationPending(false){}
|
2022-12-15 00:00:15 +01:00
|
|
|
|
virtual ~SCPINode();
|
2022-10-01 17:10:44 +02:00
|
|
|
|
|
2024-12-15 17:40:19 +01:00
|
|
|
|
bool add(SCPINode *node) {return addInternal(node, 0);}
|
|
|
|
|
|
bool remove(SCPINode *node) {return removeInternal(node, 0);}
|
|
|
|
|
|
bool add(SCPICommand *cmd) {return addInternal(cmd, 0);}
|
|
|
|
|
|
bool remove(SCPICommand *cmd) {return removeInternal(cmd, 0);}
|
2022-10-01 17:10:44 +02:00
|
|
|
|
|
2022-12-12 22:42:33 +01:00
|
|
|
|
bool addDoubleParameter(QString name, double ¶m, bool gettable = true, bool settable = true, std::function<void(void)> setCallback = nullptr);
|
|
|
|
|
|
bool addUnsignedIntParameter(QString name, unsigned int ¶m, bool gettable = true, bool settable = true, std::function<void(void)> setCallback = nullptr);
|
|
|
|
|
|
bool addBoolParameter(QString name, bool ¶m, bool gettable = true, bool settable = true, std::function<void(void)> setCallback = nullptr);
|
2025-12-02 15:29:47 +01:00
|
|
|
|
bool addStringParameter(QString name, QString ¶m, bool gettable = true, bool settable = true, std::function<void(void)> setCallback = nullptr);
|
2022-12-12 17:39:17 +01:00
|
|
|
|
|
|
|
|
|
|
bool changeName(QString newname);
|
2024-12-15 17:40:19 +01:00
|
|
|
|
QString leafName() {return name.split(":").back();}
|
2022-12-12 17:39:17 +01:00
|
|
|
|
|
2024-04-07 14:11:04 +02:00
|
|
|
|
void setOperationPending(bool pending);
|
|
|
|
|
|
|
2024-04-22 15:08:10 +02:00
|
|
|
|
protected:
|
2024-04-07 14:11:04 +02:00
|
|
|
|
bool isOperationPending();
|
|
|
|
|
|
|
2022-10-01 17:10:44 +02:00
|
|
|
|
private:
|
|
|
|
|
|
QString parse(QString cmd, SCPINode* &lastNode);
|
|
|
|
|
|
bool nameCollision(QString name);
|
|
|
|
|
|
void createCommandList(QString prefix, QString &list);
|
2024-12-15 17:40:19 +01:00
|
|
|
|
SCPINode *findSubnode(QString name);
|
|
|
|
|
|
bool addInternal(SCPINode *node, int depth);
|
|
|
|
|
|
bool removeInternal(SCPINode *node, int depth);
|
|
|
|
|
|
bool addInternal(SCPICommand *cmd, int depth);
|
|
|
|
|
|
bool removeInternal(SCPICommand *cmd, int depth);
|
2022-12-12 17:39:17 +01:00
|
|
|
|
QString name;
|
2022-10-01 17:10:44 +02:00
|
|
|
|
std::vector<SCPINode*> subnodes;
|
|
|
|
|
|
std::vector<SCPICommand*> commands;
|
|
|
|
|
|
SCPINode *parent;
|
2024-04-07 14:11:04 +02:00
|
|
|
|
bool operationPending;
|
2022-10-01 17:10:44 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class SCPI : public QObject, public SCPINode
|
|
|
|
|
|
{
|
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
public:
|
|
|
|
|
|
SCPI();
|
|
|
|
|
|
|
|
|
|
|
|
static bool match(QString s1, QString s2);
|
|
|
|
|
|
static QString alternateName(QString name);
|
|
|
|
|
|
|
|
|
|
|
|
static bool paramToDouble(QStringList params, int index, double &dest);
|
|
|
|
|
|
static bool paramToULongLong(QStringList params, int index, unsigned long long &dest);
|
|
|
|
|
|
static bool paramToLong(QStringList params, int index, long &dest);
|
|
|
|
|
|
static bool paramToBool(QStringList params, int index, bool &dest);
|
|
|
|
|
|
|
|
|
|
|
|
enum class Result {
|
|
|
|
|
|
Empty,
|
|
|
|
|
|
Error,
|
2024-04-07 14:22:57 +02:00
|
|
|
|
CmdError,
|
|
|
|
|
|
QueryError,
|
|
|
|
|
|
ExecError,
|
2022-10-01 17:10:44 +02:00
|
|
|
|
False,
|
|
|
|
|
|
True
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static QString getResultName(SCPI::Result r);
|
|
|
|
|
|
|
2024-04-07 14:11:04 +02:00
|
|
|
|
// call whenever a subnode completes an operation
|
|
|
|
|
|
void someOperationCompleted();
|
|
|
|
|
|
|
2022-10-01 17:10:44 +02:00
|
|
|
|
public slots:
|
|
|
|
|
|
void input(QString line);
|
2024-04-07 14:11:04 +02:00
|
|
|
|
void process();
|
2022-10-01 17:10:44 +02:00
|
|
|
|
signals:
|
|
|
|
|
|
void output(QString line);
|
2024-04-07 14:11:04 +02:00
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
|
|
enum class Flag {
|
|
|
|
|
|
OPC = 0x01, // Operation complete
|
|
|
|
|
|
RQC = 0x02, // device wants to become the controller (of the bus)
|
|
|
|
|
|
QYE = 0x04, // query error
|
|
|
|
|
|
DDE = 0x08, // device-dependent error
|
|
|
|
|
|
EXE = 0x10, // execution error
|
|
|
|
|
|
CME = 0x20, // command error
|
|
|
|
|
|
URQ = 0x40, // user request
|
|
|
|
|
|
PON = 0x80, // power on
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
void setFlag(Flag flag);
|
|
|
|
|
|
void clearFlag(Flag flag);
|
|
|
|
|
|
bool getFlag(Flag flag);
|
|
|
|
|
|
|
2024-04-07 14:39:27 +02:00
|
|
|
|
unsigned int SESR;
|
|
|
|
|
|
unsigned int ESE;
|
2024-04-07 14:11:04 +02:00
|
|
|
|
|
|
|
|
|
|
bool OCAS;
|
2024-04-12 12:23:54 +02:00
|
|
|
|
bool OPCsetBitScheduled;
|
2024-04-07 14:11:04 +02:00
|
|
|
|
bool OPCQueryScheduled;
|
|
|
|
|
|
bool WAIexecuting;
|
|
|
|
|
|
|
|
|
|
|
|
QList<QString> cmdQueue;
|
2024-12-02 12:10:13 +01:00
|
|
|
|
bool processing;
|
2024-12-02 14:02:34 +01:00
|
|
|
|
QSemaphore semQueue;
|
|
|
|
|
|
QSemaphore semProcessing;
|
2022-10-01 17:10:44 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif // SCPI_H
|