LibreVNA/Software/PC_Application/Device/device.h

145 lines
4.6 KiB
C
Raw Normal View History

#ifndef DEVICE_H
#define DEVICE_H
#include "../VNA_embedded/Application/Communication/Protocol.hpp"
2021-10-21 19:00:34 +08:00
#include <functional>
#include <libusb-1.0/libusb.h>
#include <thread>
#include <QObject>
#include <condition_variable>
#include <set>
#include <QQueue>
#include <QTimer>
2022-08-07 09:01:22 +08:00
#include <mutex>
2022-08-05 18:20:41 +08:00
Q_DECLARE_METATYPE(Protocol::Datapoint)
Q_DECLARE_METATYPE(Protocol::ManualStatusV1)
Q_DECLARE_METATYPE(Protocol::SpectrumAnalyzerResult)
Q_DECLARE_METATYPE(Protocol::AmplitudeCorrectionPoint)
class USBInBuffer : public QObject {
2022-08-05 18:20:41 +08:00
Q_OBJECT
public:
USBInBuffer(libusb_device_handle *handle, unsigned char endpoint, int buffer_size);
~USBInBuffer();
void removeBytes(int handled_bytes);
int getReceived() const;
uint8_t *getBuffer() const;
signals:
void DataReceived();
void TransferError();
private:
void Callback(libusb_transfer *transfer);
static void LIBUSB_CALL CallbackTrampoline(libusb_transfer *transfer);
libusb_transfer *transfer;
unsigned char *buffer;
int buffer_size;
int received_size;
bool inCallback;
std::condition_variable cv;
};
class Device : public QObject
{
Q_OBJECT
public:
enum class TransmissionResult {
Ack,
Nack,
Timeout,
InternalError,
};
Q_ENUM(TransmissionResult)
// connect to a VNA device. If serial is specified only connecting to this device, otherwise to the first one found
Device(QString serial = QString());
~Device();
static void RegisterTypes();
bool SendPacket(const Protocol::PacketInfo& packet, std::function<void(TransmissionResult)> cb = nullptr, unsigned int timeout = 500);
bool Configure(Protocol::SweepSettings settings, std::function<void(TransmissionResult)> cb = nullptr);
2022-05-18 02:07:40 +08:00
bool Configure(Protocol::SpectrumAnalyzerSettings settings, std::function<void(TransmissionResult)> cb = nullptr);
bool SetManual(Protocol::ManualControlV1 manual);
2022-05-18 02:07:40 +08:00
bool SetIdle(std::function<void(TransmissionResult)> cb = nullptr);
bool SendFirmwareChunk(Protocol::FirmwarePacket &fw);
2022-05-18 02:07:40 +08:00
bool SendCommandWithoutPayload(Protocol::PacketType type, std::function<void(TransmissionResult)> cb = nullptr);
QString serial() const;
const Protocol::DeviceInfo& Info();
static const Protocol::DeviceInfo& Info(Device *dev);
Protocol::DeviceStatusV1& StatusV1();
static const Protocol::DeviceStatusV1& StatusV1(Device *dev);
QString getLastDeviceInfoString();
2020-09-27 05:34:31 +08:00
// Returns serial numbers of all connected devices
static std::set<QString> GetDevices();
signals:
2022-08-09 00:08:40 +08:00
void DatapointReceived(Device*, Protocol::VNADatapoint<32>*);
void ManualStatusReceived(Protocol::ManualStatusV1);
2022-08-09 00:08:40 +08:00
void SpectrumResultReceived(Device*, Protocol::SpectrumAnalyzerResult);
2020-11-17 03:05:29 +08:00
void AmplitudeCorrectionPointReceived(Protocol::AmplitudeCorrectionPoint);
2021-05-02 00:34:53 +08:00
void FrequencyCorrectionReceived(float ppm);
2022-08-09 00:08:40 +08:00
void DeviceInfoUpdated(Device*);
void DeviceStatusUpdated(Device*);
void ConnectionLost();
void AckReceived();
void NackReceived();
2022-08-07 09:01:22 +08:00
void TriggerReceived(bool set);
void LogLineReceived(QString line);
void NeedsFirmwareUpdate(int usedProtocol, int requiredProtocol);
2022-08-07 09:01:22 +08:00
public slots:
void SetTrigger(bool set);
private slots:
void ReceivedData();
void ReceivedLog();
void transmissionTimeout() {
transmissionFinished(TransmissionResult::Timeout);
}
void transmissionFinished(TransmissionResult result);
signals:
void receivedAnswer(TransmissionResult result);
private:
static constexpr int EP_Data_Out_Addr = 0x01;
static constexpr int EP_Data_In_Addr = 0x81;
static constexpr int EP_Log_In_Addr = 0x82;
void USBHandleThread();
// foundCallback is called for every device that is found. If it returns true the search continues, otherwise it is aborted.
// When the search is aborted the last found device is still opened
static void SearchDevices(std::function<bool(libusb_device_handle *handle, QString serial)> foundCallback, libusb_context *context, bool ignoreOpenError);
libusb_device_handle *m_handle;
libusb_context *m_context;
USBInBuffer *dataBuffer;
USBInBuffer *logBuffer;
2022-08-22 04:20:59 +08:00
class Transmission {
public:
Protocol::PacketInfo packet;
unsigned int timeout;
std::function<void(TransmissionResult)> callback;
};
2022-08-07 09:01:22 +08:00
std::mutex transmissionMutex;
QQueue<Transmission> transmissionQueue;
bool startNextTransmission();
QTimer transmissionTimer;
bool transmissionActive;
QString m_serial;
bool m_connected;
std::thread *m_receiveThread;
Protocol::DeviceInfo info;
bool infoValid;
union {
Protocol::DeviceStatusV1 v1;
} status;
};
#endif // DEVICE_H