mirror of
https://github.com/jankae/LibreVNA.git
synced 2026-04-04 22:17:31 +00:00
Experimental direct register access
This commit is contained in:
parent
95a715233e
commit
9f33d47da0
26 changed files with 1761 additions and 8 deletions
|
|
@ -218,6 +218,47 @@ void App_Start() {
|
|||
Cal::setFrequencyCal(recv_packet.frequencyCorrection.ppm);
|
||||
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
|
||||
break;
|
||||
case Protocol::PacketType::RequestDirectRegisterInfo:
|
||||
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
|
||||
LOG_INFO("Requested register devices, sending %d packets", RegisterDevice::getNumDevices());
|
||||
for(uint8_t i=0;i<RegisterDevice::getNumDevices();i++) {
|
||||
auto dev = RegisterDevice::getDevice(i);
|
||||
Protocol::PacketInfo send;
|
||||
send.type = Protocol::PacketType::DirectRegisterInfo;
|
||||
send.directRegInfo = dev->getInfo();
|
||||
Communication::Send(send);
|
||||
}
|
||||
break;
|
||||
case Protocol::PacketType::DirectRegisterWrite:
|
||||
if(recv_packet.directRegWrite.device >= RegisterDevice::getNumDevices()) {
|
||||
// invalid device
|
||||
Communication::SendWithoutPayload(Protocol::PacketType::Nack);
|
||||
} else {
|
||||
LOG_INFO(
|
||||
"Register write: dev %u, address %u, data 0x%08x",
|
||||
recv_packet.directRegWrite.device,
|
||||
recv_packet.directRegWrite.address,
|
||||
(uint32_t) recv_packet.directRegWrite.data);
|
||||
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
|
||||
auto dev = RegisterDevice::getDevice(recv_packet.directRegWrite.device);
|
||||
dev->writeRegister(recv_packet.directRegWrite.address, recv_packet.directRegWrite.data);
|
||||
}
|
||||
break;
|
||||
case Protocol::PacketType::DirectRegisterRead:
|
||||
if(recv_packet.directRegWrite.device >= RegisterDevice::getNumDevices()) {
|
||||
// invalid device
|
||||
Communication::SendWithoutPayload(Protocol::PacketType::Nack);
|
||||
} else {
|
||||
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
|
||||
auto dev = RegisterDevice::getDevice(recv_packet.directRegWrite.device);
|
||||
Protocol::PacketInfo send;
|
||||
send.type = Protocol::PacketType::DirectRegisterWrite;
|
||||
send.directRegWrite.device = recv_packet.directRegRead.device;
|
||||
send.directRegWrite.address = recv_packet.directRegRead.address;
|
||||
send.directRegWrite.data = dev->readRegister(recv_packet.directRegRead.address);
|
||||
Communication::Send(send);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// this packet type is not supported
|
||||
Communication::SendWithoutPayload(Protocol::PacketType::Nack);
|
||||
|
|
|
|||
|
|
@ -100,6 +100,9 @@ uint16_t Protocol::EncodePacket(const PacketInfo &packet, uint8_t *dest, uint16_
|
|||
case PacketType::SourceCalPoint:
|
||||
case PacketType::ReceiverCalPoint: payload_size = sizeof(packet.amplitudePoint); break;
|
||||
case PacketType::FrequencyCorrection: payload_size = sizeof(packet.frequencyCorrection); break;
|
||||
case PacketType::DirectRegisterInfo: payload_size = sizeof(packet.directRegInfo); break;
|
||||
case PacketType::DirectRegisterWrite: payload_size = sizeof(packet.directRegWrite); break;
|
||||
case PacketType::DirectRegisterRead: payload_size = sizeof(packet.directRegRead); break;
|
||||
case PacketType::Ack:
|
||||
case PacketType::PerformFirmwareUpdate:
|
||||
case PacketType::ClearFlash:
|
||||
|
|
@ -109,6 +112,7 @@ uint16_t Protocol::EncodePacket(const PacketInfo &packet, uint8_t *dest, uint16_
|
|||
case PacketType::RequestReceiverCal:
|
||||
case PacketType::SetIdle:
|
||||
case PacketType::RequestFrequencyCorrection:
|
||||
case PacketType::RequestDirectRegisterInfo:
|
||||
// no payload
|
||||
break;
|
||||
case PacketType::None:
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
namespace Protocol {
|
||||
|
||||
static constexpr uint16_t Version = 5;
|
||||
static constexpr uint16_t Version = 6;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
|
|
@ -68,6 +68,7 @@ using DeviceInfo = struct _deviceInfo {
|
|||
uint32_t limits_maxRBW;
|
||||
uint8_t limits_maxAmplitudePoints;
|
||||
uint64_t limits_maxFreqHarmonic;
|
||||
uint8_t num_directRegisterDevices; // number of peripheral chips whos registers are exposed via the USB API (for debugging)
|
||||
};
|
||||
|
||||
using ManualStatus = struct _manualstatus {
|
||||
|
|
@ -156,6 +157,25 @@ using FrequencyCorrection = struct _frequencycorrection {
|
|||
float ppm;
|
||||
};
|
||||
|
||||
using DirectRegisterInfo = struct _directregisterinfo {
|
||||
uint8_t num;
|
||||
char type[20]; // Chip partnumber
|
||||
char name[20]; // Arbitrary name
|
||||
};
|
||||
|
||||
using DirectRegisterWrite = struct _directregisterwrite {
|
||||
uint8_t device;
|
||||
uint32_t address;
|
||||
uint64_t data;
|
||||
};
|
||||
|
||||
using DirectRegisterRead = struct _directregisterread {
|
||||
// Device will respond with DirectRegisterWrite
|
||||
uint8_t device;
|
||||
// uint8_t read_all:1; // if set to one, address is ignored and all registers returned (each in own packet)
|
||||
uint32_t address;
|
||||
};
|
||||
|
||||
enum class PacketType : uint8_t {
|
||||
None = 0,
|
||||
Datapoint = 1,
|
||||
|
|
@ -180,6 +200,10 @@ enum class PacketType : uint8_t {
|
|||
SetIdle = 20,
|
||||
RequestFrequencyCorrection = 21,
|
||||
FrequencyCorrection = 22,
|
||||
RequestDirectRegisterInfo = 23,
|
||||
DirectRegisterInfo = 24,
|
||||
DirectRegisterWrite = 25,
|
||||
DirectRegisterRead = 26,
|
||||
};
|
||||
|
||||
using PacketInfo = struct _packetinfo {
|
||||
|
|
@ -197,6 +221,9 @@ using PacketInfo = struct _packetinfo {
|
|||
SpectrumAnalyzerResult spectrumResult;
|
||||
AmplitudeCorrectionPoint amplitudePoint;
|
||||
FrequencyCorrection frequencyCorrection;
|
||||
DirectRegisterInfo directRegInfo;
|
||||
DirectRegisterWrite directRegWrite;
|
||||
DirectRegisterRead directRegRead;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
24
Software/VNA_embedded/Application/Drivers/RegisterDevice.cpp
Normal file
24
Software/VNA_embedded/Application/Drivers/RegisterDevice.cpp
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include <RegisterDevice.hpp>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
uint8_t RegisterDevice::cnt = 0;
|
||||
std::array<RegisterDevice*, RegisterDevice::maxDevices> RegisterDevice::devices;
|
||||
|
||||
Protocol::DirectRegisterInfo RegisterDevice::getInfo() {
|
||||
Protocol::DirectRegisterInfo i;
|
||||
i.num = num;
|
||||
strncpy(i.name, name, sizeof(i.name));
|
||||
i.name[sizeof(i.name) - 1] = '\0';
|
||||
strncpy(i.type, type, sizeof(i.type));
|
||||
i.type[sizeof(i.type) - 1] = '\0';
|
||||
return i;
|
||||
}
|
||||
|
||||
RegisterDevice* RegisterDevice::getDevice(uint8_t num) {
|
||||
if(num < cnt) {
|
||||
return devices[num];
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
41
Software/VNA_embedded/Application/Drivers/RegisterDevice.hpp
Normal file
41
Software/VNA_embedded/Application/Drivers/RegisterDevice.hpp
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
#include "Protocol.hpp"
|
||||
|
||||
extern int global;
|
||||
|
||||
class RegisterDevice {
|
||||
public:
|
||||
constexpr RegisterDevice(const char *type, const char *name) :
|
||||
type(type),
|
||||
name(name),
|
||||
num(0)
|
||||
{
|
||||
num = cnt;
|
||||
if(cnt < maxDevices) {
|
||||
devices[cnt] = this;
|
||||
cnt++;
|
||||
} else {
|
||||
// not enough room in array. A debug message would be useful here
|
||||
// but the constructor is called before any hardware initialization
|
||||
// so we can do nothing here
|
||||
}
|
||||
}
|
||||
virtual void writeRegister(uint32_t address, uint64_t data) = 0;
|
||||
virtual uint64_t readRegister(uint32_t address) = 0;
|
||||
|
||||
Protocol::DirectRegisterInfo getInfo();
|
||||
|
||||
static uint8_t getNumDevices() { return cnt;};
|
||||
static RegisterDevice *getDevice(uint8_t num);
|
||||
|
||||
private:
|
||||
static constexpr uint8_t maxDevices = 10;
|
||||
static std::array<RegisterDevice*,maxDevices> devices;
|
||||
static uint8_t cnt;
|
||||
const char *type;
|
||||
const char *name;
|
||||
uint8_t num;
|
||||
};
|
||||
|
|
@ -417,3 +417,18 @@ uint8_t MAX2871::GetTemp() {
|
|||
// convert to celsius and return
|
||||
return 95 - 1.14f * ADC_raw;
|
||||
}
|
||||
|
||||
void MAX2871::writeRegister(uint32_t address, uint64_t data) {
|
||||
if(address <= 5) {
|
||||
regs[address] = (uint32_t) data;
|
||||
Update();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t MAX2871::readRegister(uint32_t address) {
|
||||
if(address <= 5) {
|
||||
return regs[address];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include "stm.hpp"
|
||||
#include "RegisterDevice.hpp"
|
||||
|
||||
class MAX2871 {
|
||||
class MAX2871 : public RegisterDevice {
|
||||
public:
|
||||
constexpr MAX2871(SPI_HandleTypeDef *hspi, GPIO_TypeDef *LE = nullptr,
|
||||
constexpr MAX2871(const char *name, SPI_HandleTypeDef *hspi, GPIO_TypeDef *LE = nullptr,
|
||||
uint16_t LEpin = 0, GPIO_TypeDef *RF_EN = nullptr,
|
||||
uint16_t RF_ENpin = 0, GPIO_TypeDef *LD = nullptr, uint16_t LDpin = 0,
|
||||
GPIO_TypeDef *CE = nullptr, uint16_t CEpin = 0,
|
||||
GPIO_TypeDef *MUX = nullptr, uint16_t MUXpin = 0) :
|
||||
regs(), f_PFD(0),
|
||||
RegisterDevice("MAX2871", name),
|
||||
regs(), f_PFD(0),
|
||||
hspi(hspi),
|
||||
CE(CE), CEpin(CEpin),
|
||||
LE(LE), LEpin(LEpin),
|
||||
|
|
@ -60,6 +62,9 @@ public:
|
|||
uint64_t GetActualFrequency() {
|
||||
return outputFrequency;
|
||||
}
|
||||
|
||||
void writeRegister(uint32_t address, uint64_t data) override;
|
||||
uint64_t readRegister(uint32_t address) override;
|
||||
private:
|
||||
static constexpr uint64_t MaxFreq = 6100000000; // 6GHz according to datasheet, but slight overclocking is possible
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "HW_HAL.hpp"
|
||||
|
||||
Si5351C HWHAL::Si5351 = Si5351C(&hi2c2, 26000000);
|
||||
MAX2871 HWHAL::Source = MAX2871(&hspi1, FPGA_CS_GPIO_Port, FPGA_CS_Pin, nullptr, 0, nullptr, 0, nullptr, 0, GPIOA, GPIO_PIN_6);
|
||||
MAX2871 HWHAL::LO1 = MAX2871(&hspi1, FPGA_CS_GPIO_Port, FPGA_CS_Pin, nullptr, 0, nullptr, 0, nullptr, 0, GPIOA, GPIO_PIN_6);
|
||||
MAX2871 HWHAL::Source = MAX2871("Source", &hspi1, FPGA_CS_GPIO_Port, FPGA_CS_Pin, nullptr, 0, nullptr, 0, nullptr, 0, GPIOA, GPIO_PIN_6);
|
||||
MAX2871 HWHAL::LO1 = MAX2871("1.LO", &hspi1, FPGA_CS_GPIO_Port, FPGA_CS_Pin, nullptr, 0, nullptr, 0, nullptr, 0, GPIOA, GPIO_PIN_6);
|
||||
extern SPI_HandleTypeDef hspi1;
|
||||
Flash HWHAL::flash = Flash(&hspi1, FLASH_CS_GPIO_Port, FLASH_CS_Pin);
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ static constexpr int16_t LowBandMaxPower = -190;
|
|||
static constexpr int16_t HighBandMinPower = -1060;
|
||||
static constexpr int16_t HighBandMaxPower = -160;
|
||||
|
||||
static constexpr uint8_t registerDevices = 2;
|
||||
|
||||
static constexpr Protocol::DeviceInfo Info = {
|
||||
.ProtocolVersion = Protocol::Version,
|
||||
.FW_major = FW_MAJOR,
|
||||
|
|
@ -75,6 +77,7 @@ static constexpr Protocol::DeviceInfo Info = {
|
|||
.limits_maxRBW = (uint32_t) (ADCSamplerate * 2.23f / MinSamples),
|
||||
.limits_maxAmplitudePoints = Cal::maxPoints,
|
||||
.limits_maxFreqHarmonic = 18000000000,
|
||||
.num_directRegisterDevices = registerDevices,
|
||||
};
|
||||
|
||||
enum class Mode {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue