mirror of
https://github.com/jankae/LibreVNA.git
synced 2026-04-04 14:07:30 +00:00
embedded code copied from jankae/VNA and adjusted for STM32G4
This commit is contained in:
parent
7af204b349
commit
30d4ebe37b
215 changed files with 186208 additions and 0 deletions
|
|
@ -0,0 +1,65 @@
|
|||
#include <Communication.h>
|
||||
|
||||
#include "stm.hpp"
|
||||
#include "../App.h"
|
||||
#include <string.h>
|
||||
#include "USB/usb.h"
|
||||
|
||||
static uint8_t inputBuffer[1024];
|
||||
uint16_t inputCnt = 0;
|
||||
static uint8_t outputBuffer[1024];
|
||||
|
||||
//#include "usbd_def.h"
|
||||
//#include "usbd_cdc_if.h"
|
||||
|
||||
//extern USBD_HandleTypeDef hUsbDeviceFS;
|
||||
|
||||
void Communication::Input(const uint8_t *buf, uint16_t len) {
|
||||
if (inputCnt + len < sizeof(inputBuffer)) {
|
||||
// add received data to input buffer
|
||||
memcpy(&inputBuffer[inputCnt], buf, len);
|
||||
inputCnt += len;
|
||||
}
|
||||
Protocol::PacketInfo packet;
|
||||
uint16_t handled_len;
|
||||
do {
|
||||
handled_len = Protocol::DecodeBuffer(inputBuffer, inputCnt, &packet);
|
||||
if (handled_len == inputCnt) {
|
||||
// complete input buffer used up, reset counter
|
||||
inputCnt = 0;
|
||||
} else {
|
||||
// only used part of the buffer, move up remaining bytes
|
||||
uint16_t remaining = inputCnt - handled_len;
|
||||
memmove(inputBuffer, &inputBuffer[handled_len], remaining);
|
||||
inputCnt = remaining;
|
||||
}
|
||||
switch(packet.type) {
|
||||
case Protocol::PacketType::SweepSettings:
|
||||
App::NewSettings(packet.settings);
|
||||
break;
|
||||
case Protocol::PacketType::ManualControl:
|
||||
App::SetManual(packet.manual);
|
||||
break;
|
||||
}
|
||||
} while (handled_len > 0);
|
||||
}
|
||||
|
||||
bool Communication::Send(Protocol::PacketInfo packet) {
|
||||
uint16_t len = Protocol::EncodePacket(packet, outputBuffer,
|
||||
sizeof(outputBuffer));
|
||||
return usb_transmit(outputBuffer, len);
|
||||
// if (hUsbDeviceFS.dev_state == USBD_STATE_CONFIGURED) {
|
||||
// uint16_t len = Protocol::EncodePacket(packet, outputBuffer,
|
||||
// sizeof(outputBuffer));
|
||||
// while (CDC_Transmit_FS(outputBuffer, len) != USBD_OK)
|
||||
// ;
|
||||
// return true;
|
||||
// } else {
|
||||
// // not connected, do not attempt to send
|
||||
// return false;
|
||||
// }
|
||||
}
|
||||
|
||||
void communication_usb_input(const uint8_t *buf, uint16_t len) {
|
||||
Communication::Input(buf, len);
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "Protocol.hpp"
|
||||
|
||||
namespace Communication {
|
||||
|
||||
void Input(const uint8_t *buf, uint16_t len);
|
||||
bool Send(Protocol::PacketInfo packet);
|
||||
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
void communication_usb_input(const uint8_t *buf, uint16_t len);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
422
Software/VNA_embedded/Application/Communication/Protocol.cpp
Normal file
422
Software/VNA_embedded/Application/Communication/Protocol.cpp
Normal file
|
|
@ -0,0 +1,422 @@
|
|||
#include "Protocol.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
/*
|
||||
* General packet format:
|
||||
* 1. 1 byte header
|
||||
* 2. 2 byte overall packet length (with header and checksum)
|
||||
* 3. packet type
|
||||
* 4. packet payload
|
||||
* 5. 4 byte CRC32 (with header)
|
||||
*/
|
||||
|
||||
static constexpr uint8_t header = 0x5A;
|
||||
static constexpr uint8_t header_size = 4;
|
||||
|
||||
#define CRC32_POLYGON 0xEDB88320
|
||||
uint32_t CRC32(uint32_t crc, const void *data, uint32_t len) {
|
||||
uint8_t *u8buf = (uint8_t*) data;
|
||||
int k;
|
||||
|
||||
crc = ~crc;
|
||||
while (len--) {
|
||||
crc ^= *u8buf++;
|
||||
for (k = 0; k < 8; k++)
|
||||
crc = crc & 1 ? (crc >> 1) ^ CRC32_POLYGON : crc >> 1;
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
class Encoder {
|
||||
public:
|
||||
Encoder(uint8_t *buf, uint16_t size) :
|
||||
buf(buf),
|
||||
bufSize(size),
|
||||
usedSize(0),
|
||||
bitpos(0) {
|
||||
memset(buf, 0, size);
|
||||
};
|
||||
template<typename T> bool add(T data) {
|
||||
if(bitpos != 0) {
|
||||
// add padding to next byte boundary
|
||||
bitpos = 0;
|
||||
usedSize++;
|
||||
}
|
||||
if(bufSize - usedSize < (long) sizeof(T)) {
|
||||
// not enough space left
|
||||
return false;
|
||||
}
|
||||
memcpy(&buf[usedSize], &data, sizeof(T));
|
||||
usedSize += sizeof(T);
|
||||
return true;
|
||||
}
|
||||
bool addBits(uint8_t value, uint8_t bits) {
|
||||
if(bits >= 8 || usedSize >= bufSize) {
|
||||
return false;
|
||||
}
|
||||
buf[usedSize] |= (value << bitpos) & 0xFF;
|
||||
bitpos += bits;
|
||||
if(bitpos > 8) {
|
||||
// the value did not fit completely into the current byte
|
||||
if(usedSize >= bufSize - 1) {
|
||||
// already at maximum limit, not enough space for remaining bits
|
||||
return false;
|
||||
}
|
||||
// move access to next byte
|
||||
bitpos -= 8;
|
||||
usedSize++;
|
||||
// add remaining bytes
|
||||
buf[usedSize] = value >> (bits - bitpos);
|
||||
} else if(bitpos == 8) {
|
||||
bitpos = 0;
|
||||
usedSize++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
uint16_t getSize() const {
|
||||
if(bitpos == 0) {
|
||||
return usedSize;
|
||||
} else {
|
||||
return usedSize + 1;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
uint8_t *buf;
|
||||
uint16_t bufSize;
|
||||
uint16_t usedSize;
|
||||
uint8_t bitpos;
|
||||
};
|
||||
|
||||
class Decoder {
|
||||
public:
|
||||
Decoder(uint8_t *buf) :
|
||||
buf(buf),
|
||||
usedSize(0),
|
||||
bitpos(0) {};
|
||||
template<typename T> void get(T &t) {
|
||||
if(bitpos != 0) {
|
||||
// add padding to next byte boundary
|
||||
bitpos = 0;
|
||||
usedSize++;
|
||||
}
|
||||
// still enough bytes available
|
||||
memcpy(&t, &buf[usedSize], sizeof(T));
|
||||
usedSize += sizeof(T);
|
||||
}
|
||||
uint8_t getBits(uint8_t bits) {
|
||||
if(bits >= 8) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t mask = 0x00;
|
||||
for(uint8_t i=0;i<bits;i++) {
|
||||
mask <<= 1;
|
||||
mask |= 0x01;
|
||||
}
|
||||
uint8_t value = (buf[usedSize] >> bitpos) & mask;
|
||||
bitpos += bits;
|
||||
if(bitpos > 8) {
|
||||
// the current byte did not contain the complete value
|
||||
// move access to next byte
|
||||
bitpos -= 8;
|
||||
usedSize++;
|
||||
// get remaining bits
|
||||
value |= (buf[usedSize] << (bits - bitpos)) & mask;
|
||||
} else if(bitpos == 8) {
|
||||
bitpos = 0;
|
||||
usedSize++;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
private:
|
||||
uint8_t *buf;
|
||||
uint16_t usedSize;
|
||||
uint8_t bitpos;
|
||||
};
|
||||
|
||||
static Protocol::Datapoint DecodeDatapoint(uint8_t *buf) {
|
||||
Protocol::Datapoint d;
|
||||
Decoder e(buf);
|
||||
e.get<float>(d.real_S11);
|
||||
e.get<float>(d.imag_S11);
|
||||
e.get<float>(d.real_S21);
|
||||
e.get<float>(d.imag_S21);
|
||||
e.get<float>(d.real_S12);
|
||||
e.get<float>(d.imag_S12);
|
||||
e.get<float>(d.real_S22);
|
||||
e.get<float>(d.imag_S22);
|
||||
e.get<uint64_t>(d.frequency);
|
||||
e.get<uint16_t>(d.pointNum);
|
||||
return d;
|
||||
}
|
||||
static uint16_t EncodeDatapoint(Protocol::Datapoint d, uint8_t *buf,
|
||||
uint16_t bufSize) {
|
||||
Encoder e(buf, bufSize);
|
||||
e.add<float>(d.real_S11);
|
||||
e.add<float>(d.imag_S11);
|
||||
e.add<float>(d.real_S21);
|
||||
e.add<float>(d.imag_S21);
|
||||
e.add<float>(d.real_S12);
|
||||
e.add<float>(d.imag_S12);
|
||||
e.add<float>(d.real_S22);
|
||||
e.add<float>(d.imag_S22);
|
||||
e.add<uint64_t>(d.frequency);
|
||||
e.add<uint16_t>(d.pointNum);
|
||||
return e.getSize();
|
||||
}
|
||||
|
||||
static Protocol::SweepSettings DecodeSweepSettings(uint8_t *buf) {
|
||||
Protocol::SweepSettings d;
|
||||
Decoder e(buf);
|
||||
e.get<uint64_t>(d.f_start);
|
||||
e.get<uint64_t>(d.f_stop);
|
||||
e.get<uint16_t>(d.points);
|
||||
e.get<uint32_t>(d.if_bandwidth);
|
||||
e.get<int16_t>(d.cdbm_excitation);
|
||||
return d;
|
||||
}
|
||||
static uint16_t EncodeSweepSettings(Protocol::SweepSettings d, uint8_t *buf,
|
||||
uint16_t bufSize) {
|
||||
Encoder e(buf, bufSize);
|
||||
e.add<uint64_t>(d.f_start);
|
||||
e.add<uint64_t>(d.f_stop);
|
||||
e.add<uint16_t>(d.points);
|
||||
e.add<uint32_t>(d.if_bandwidth);
|
||||
e.add<int16_t>(d.cdbm_excitation);
|
||||
return e.getSize();
|
||||
}
|
||||
|
||||
static Protocol::DeviceInfo DecodeDeviceInfo(uint8_t *buf) {
|
||||
Protocol::DeviceInfo d;
|
||||
Decoder e(buf);
|
||||
e.get<uint16_t>(d.FW_major);
|
||||
e.get<uint16_t>(d.FW_minor);
|
||||
e.get<char>(d.HW_Revision);
|
||||
d.extRefAvailable = e.getBits(1);
|
||||
d.extRefInUse = e.getBits(1);
|
||||
d.FPGA_configured = e.getBits(1);
|
||||
d.source_locked = e.getBits(1);
|
||||
d.LO1_locked = e.getBits(1);
|
||||
d.ADC_overload = e.getBits(1);
|
||||
e.get<uint8_t>(d.temperatures.source);
|
||||
e.get<uint8_t>(d.temperatures.LO1);
|
||||
e.get<uint8_t>(d.temperatures.MCU);
|
||||
return d;
|
||||
}
|
||||
static uint16_t EncodeDeviceInfo(Protocol::DeviceInfo d, uint8_t *buf,
|
||||
uint16_t bufSize) {
|
||||
Encoder e(buf, bufSize);
|
||||
e.add<uint16_t>(d.FW_major);
|
||||
e.add<uint16_t>(d.FW_minor);
|
||||
e.add<char>(d.HW_Revision);
|
||||
e.addBits(d.extRefAvailable, 1);
|
||||
e.addBits(d.extRefInUse, 1);
|
||||
e.addBits(d.FPGA_configured, 1);
|
||||
e.addBits(d.source_locked, 1);
|
||||
e.addBits(d.LO1_locked, 1);
|
||||
e.addBits(d.ADC_overload, 1);
|
||||
e.add<uint8_t>(d.temperatures.source);
|
||||
e.add<uint8_t>(d.temperatures.LO1);
|
||||
e.add<uint8_t>(d.temperatures.MCU);
|
||||
return e.getSize();
|
||||
}
|
||||
|
||||
static Protocol::ManualStatus DecodeStatus(uint8_t *buf) {
|
||||
Protocol::ManualStatus d;
|
||||
Decoder e(buf);
|
||||
e.get<int16_t>(d.port1min);
|
||||
e.get<int16_t>(d.port1max);
|
||||
e.get<int16_t>(d.port2min);
|
||||
e.get<int16_t>(d.port2max);
|
||||
e.get<int16_t>(d.refmin);
|
||||
e.get<int16_t>(d.refmax);
|
||||
e.get<float>(d.port1real);
|
||||
e.get<float>(d.port1imag);
|
||||
e.get<float>(d.port2real);
|
||||
e.get<float>(d.port2imag);
|
||||
e.get<float>(d.refreal);
|
||||
e.get<float>(d.refimag);
|
||||
e.get<uint8_t>(d.temp_source);
|
||||
e.get<uint8_t>(d.temp_LO);
|
||||
d.source_locked = e.getBits( 1);
|
||||
d.LO_locked = e.getBits(1);
|
||||
return d;
|
||||
}
|
||||
static uint16_t EncodeStatus(Protocol::ManualStatus d, uint8_t *buf,
|
||||
uint16_t bufSize) {
|
||||
Encoder e(buf, bufSize);
|
||||
e.add<int16_t>(d.port1min);
|
||||
e.add<int16_t>(d.port1max);
|
||||
e.add<int16_t>(d.port2min);
|
||||
e.add<int16_t>(d.port2max);
|
||||
e.add<int16_t>(d.refmin);
|
||||
e.add<int16_t>(d.refmax);
|
||||
e.add<float>(d.port1real);
|
||||
e.add<float>(d.port1imag);
|
||||
e.add<float>(d.port2real);
|
||||
e.add<float>(d.port2imag);
|
||||
e.add<float>(d.refreal);
|
||||
e.add<float>(d.refimag);
|
||||
e.add<uint8_t>(d.temp_source);
|
||||
e.add<uint8_t>(d.temp_LO);
|
||||
e.addBits(d.source_locked, 1);
|
||||
e.addBits(d.LO_locked, 1);
|
||||
return e.getSize();
|
||||
}
|
||||
|
||||
static Protocol::ManualControl DecodeManualControl(uint8_t *buf) {
|
||||
Protocol::ManualControl d;
|
||||
Decoder e(buf);
|
||||
d.SourceHighCE = e.getBits(1);
|
||||
d.SourceHighRFEN = e.getBits(1);
|
||||
d.SourceHighPower = e.getBits(2);
|
||||
d.SourceHighLowpass = e.getBits(2);
|
||||
e.get<uint64_t>(d.SourceHighFrequency);
|
||||
d.SourceLowEN = e.getBits(1);
|
||||
d.SourceLowPower = e.getBits( 2);
|
||||
e.get<uint32_t>(d.SourceLowFrequency);
|
||||
d.attenuator = e.getBits(7);
|
||||
d.SourceHighband = e.getBits(1);
|
||||
d.AmplifierEN = e.getBits(1);
|
||||
d.PortSwitch = e.getBits(1);
|
||||
d.LO1CE = e.getBits(1);
|
||||
d.LO1RFEN = e.getBits(1);
|
||||
e.get<uint64_t>(d.LO1Frequency);
|
||||
d.LO2EN = e.getBits(1);
|
||||
e.get<uint32_t>(d.LO2Frequency);
|
||||
d.Port1EN = e.getBits(1);
|
||||
d.Port2EN = e.getBits(1);
|
||||
d.RefEN = e.getBits(1);
|
||||
e.get<uint32_t>(d.Samples);
|
||||
return d;
|
||||
}
|
||||
static uint16_t EncodeManualControl(Protocol::ManualControl d, uint8_t *buf,
|
||||
uint16_t bufSize) {
|
||||
Encoder e(buf, bufSize);
|
||||
e.addBits(d.SourceHighCE, 1);
|
||||
e.addBits(d.SourceHighRFEN, 1);
|
||||
e.addBits(d.SourceHighPower, 2);
|
||||
e.addBits(d.SourceHighLowpass, 2);
|
||||
e.add<uint64_t>(d.SourceHighFrequency);
|
||||
e.addBits(d.SourceLowEN, 1);
|
||||
e.addBits(d.SourceLowPower, 2);
|
||||
e.add<uint32_t>(d.SourceLowFrequency);
|
||||
e.addBits(d.attenuator, 7);
|
||||
e.addBits(d.SourceHighband, 1);
|
||||
e.addBits(d.AmplifierEN, 1);
|
||||
e.addBits(d.PortSwitch, 1);
|
||||
e.addBits(d.LO1CE, 1);
|
||||
e.addBits(d.LO1RFEN, 1);
|
||||
e.add<uint64_t>(d.LO1Frequency);
|
||||
e.addBits(d.LO2EN, 1);
|
||||
e.add<uint32_t>(d.LO2Frequency);
|
||||
e.addBits(d.Port1EN, 1);
|
||||
e.addBits(d.Port2EN, 1);
|
||||
e.addBits(d.RefEN, 1);
|
||||
e.add<uint32_t>(d.Samples);
|
||||
return e.getSize();
|
||||
}
|
||||
|
||||
uint16_t Protocol::DecodeBuffer(uint8_t *buf, uint16_t len, PacketInfo *info) {
|
||||
if (!info || !len) {
|
||||
info->type = PacketType::None;
|
||||
return 0;
|
||||
}
|
||||
uint8_t *data = buf;
|
||||
/* Remove any out-of-order bytes in front of the frame */
|
||||
while (*data != header) {
|
||||
data++;
|
||||
if(--len == 0) {
|
||||
/* Reached end of data */
|
||||
/* No frame contained in data */
|
||||
info->type = PacketType::None;
|
||||
return data - buf;
|
||||
}
|
||||
}
|
||||
/* At this point, data points to the beginning of the frame */
|
||||
if(len < header_size) {
|
||||
/* the frame header has not been completely received */
|
||||
info->type = PacketType::None;
|
||||
return data - buf;
|
||||
}
|
||||
|
||||
/* Evaluate frame size */
|
||||
uint16_t length = *(uint16_t*) &data[1];
|
||||
if(len < length) {
|
||||
/* The frame payload has not been completely received */
|
||||
info->type = PacketType::None;
|
||||
return data - buf;
|
||||
}
|
||||
|
||||
/* The complete frame has been received, check checksum */
|
||||
uint32_t crc = *(uint32_t*) &data[length - 4];
|
||||
uint32_t compare = CRC32(0, data, length - 4);
|
||||
if(crc != compare) {
|
||||
// CRC mismatch, remove header
|
||||
data += 1;
|
||||
info->type = PacketType::None;
|
||||
return data - buf;
|
||||
}
|
||||
|
||||
// Valid packet, extract packet info
|
||||
info->type = (PacketType) data[3];
|
||||
switch (info->type) {
|
||||
case PacketType::Datapoint:
|
||||
info->datapoint = DecodeDatapoint(&data[4]);
|
||||
break;
|
||||
case PacketType::SweepSettings:
|
||||
info->settings = DecodeSweepSettings(&data[4]);
|
||||
break;
|
||||
case PacketType::DeviceInfo:
|
||||
info->info = DecodeDeviceInfo(&data[4]);
|
||||
break;
|
||||
case PacketType::Status:
|
||||
info->status = DecodeStatus(&data[4]);
|
||||
break;
|
||||
case PacketType::ManualControl:
|
||||
info->manual = DecodeManualControl(&data[4]);
|
||||
break;
|
||||
case PacketType::None:
|
||||
break;
|
||||
}
|
||||
|
||||
return data - buf + length;
|
||||
}
|
||||
|
||||
uint16_t Protocol::EncodePacket(PacketInfo packet, uint8_t *dest, uint16_t destsize) {
|
||||
uint16_t payload_size = 0;
|
||||
switch (packet.type) {
|
||||
case PacketType::Datapoint:
|
||||
payload_size = EncodeDatapoint(packet.datapoint, &dest[4], destsize - 8);
|
||||
break;
|
||||
case PacketType::SweepSettings:
|
||||
payload_size = EncodeSweepSettings(packet.settings, &dest[4], destsize - 8);
|
||||
break;
|
||||
case PacketType::DeviceInfo:
|
||||
payload_size = EncodeDeviceInfo(packet.info, &dest[4], destsize - 8);
|
||||
break;
|
||||
case PacketType::Status:
|
||||
payload_size = EncodeStatus(packet.status, &dest[4], destsize - 8);
|
||||
break;
|
||||
case PacketType::ManualControl:
|
||||
payload_size = EncodeManualControl(packet.manual, &dest[4], destsize - 8);
|
||||
break;
|
||||
case PacketType::None:
|
||||
break;
|
||||
}
|
||||
if (payload_size == 0 || payload_size + 8 > destsize) {
|
||||
// encoding failed, buffer too small
|
||||
return 0;
|
||||
}
|
||||
// Write header
|
||||
dest[0] = header;
|
||||
uint16_t overall_size = payload_size + 8;
|
||||
memcpy(&dest[1], &overall_size, 2);
|
||||
dest[3] = (int) packet.type;
|
||||
// Calculate checksum
|
||||
uint32_t crc = CRC32(0, dest, overall_size - 4);
|
||||
memcpy(&dest[overall_size - 4], &crc, 4);
|
||||
return overall_size;
|
||||
}
|
||||
|
||||
109
Software/VNA_embedded/Application/Communication/Protocol.hpp
Normal file
109
Software/VNA_embedded/Application/Communication/Protocol.hpp
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Protocol {
|
||||
|
||||
// When changing/adding/removing variables from these structs also adjust the decode/encode functions in Protocol.cpp
|
||||
|
||||
using Datapoint = struct _datapoint {
|
||||
float real_S11, imag_S11;
|
||||
float real_S21, imag_S21;
|
||||
float real_S12, imag_S12;
|
||||
float real_S22, imag_S22;
|
||||
uint64_t frequency;
|
||||
uint16_t pointNum;
|
||||
};
|
||||
|
||||
using SweepSettings = struct _sweepSettings {
|
||||
uint64_t f_start;
|
||||
uint64_t f_stop;
|
||||
uint16_t points;
|
||||
uint32_t if_bandwidth;
|
||||
int16_t cdbm_excitation; // in 1/100 dbm
|
||||
};
|
||||
|
||||
using DeviceInfo = struct _deviceInfo {
|
||||
uint16_t FW_major;
|
||||
uint16_t FW_minor;
|
||||
char HW_Revision;
|
||||
uint8_t extRefAvailable:1;
|
||||
uint8_t extRefInUse:1;
|
||||
uint8_t FPGA_configured:1;
|
||||
uint8_t source_locked:1;
|
||||
uint8_t LO1_locked:1;
|
||||
uint8_t ADC_overload:1;
|
||||
struct {
|
||||
uint8_t source;
|
||||
uint8_t LO1;
|
||||
uint8_t MCU;
|
||||
} temperatures;
|
||||
};
|
||||
|
||||
using ManualStatus = struct _manualstatus {
|
||||
int16_t port1min, port1max;
|
||||
int16_t port2min, port2max;
|
||||
int16_t refmin, refmax;
|
||||
float port1real, port1imag;
|
||||
float port2real, port2imag;
|
||||
float refreal, refimag;
|
||||
uint8_t temp_source;
|
||||
uint8_t temp_LO;
|
||||
uint8_t source_locked :1;
|
||||
uint8_t LO_locked :1;
|
||||
};
|
||||
|
||||
using ManualControl = struct _manualControl {
|
||||
// Highband Source
|
||||
uint8_t SourceHighCE :1;
|
||||
uint8_t SourceHighRFEN :1;
|
||||
uint8_t SourceHighPower :2;
|
||||
uint8_t SourceHighLowpass :2;
|
||||
uint64_t SourceHighFrequency;
|
||||
// Lowband Source
|
||||
uint8_t SourceLowEN :1;
|
||||
uint8_t SourceLowPower :2;
|
||||
uint32_t SourceLowFrequency;
|
||||
// Source signal path
|
||||
uint8_t attenuator :7;
|
||||
uint8_t SourceHighband :1;
|
||||
uint8_t AmplifierEN :1;
|
||||
uint8_t PortSwitch :1;
|
||||
// LO1
|
||||
uint8_t LO1CE :1;
|
||||
uint8_t LO1RFEN :1;
|
||||
uint64_t LO1Frequency;
|
||||
// LO2
|
||||
uint8_t LO2EN :1;
|
||||
uint32_t LO2Frequency;
|
||||
// Acquisition
|
||||
uint8_t Port1EN :1;
|
||||
uint8_t Port2EN :1;
|
||||
uint8_t RefEN :1;
|
||||
uint32_t Samples;
|
||||
};
|
||||
|
||||
enum class PacketType : uint8_t {
|
||||
None,
|
||||
Datapoint,
|
||||
SweepSettings,
|
||||
Status,
|
||||
ManualControl,
|
||||
DeviceInfo,
|
||||
};
|
||||
|
||||
using PacketInfo = struct _packetinfo {
|
||||
PacketType type;
|
||||
union {
|
||||
Datapoint datapoint;
|
||||
SweepSettings settings;
|
||||
DeviceInfo info;
|
||||
ManualControl manual;
|
||||
ManualStatus status;
|
||||
};
|
||||
};
|
||||
|
||||
uint16_t DecodeBuffer(uint8_t *buf, uint16_t len, PacketInfo *info);
|
||||
uint16_t EncodePacket(PacketInfo packet, uint8_t *dest, uint16_t destsize);
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue