HAL layer for VNA functionality to use similar firmware on both hardware revisions

This commit is contained in:
Jan Käberich 2020-09-11 23:08:30 +02:00
parent f4a6b24a8e
commit 6960498fcb
12 changed files with 164 additions and 87 deletions

View File

@ -151,6 +151,8 @@
<listOptionValue builtIn="false" value="../Inc"/> <listOptionValue builtIn="false" value="../Inc"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Application/Drivers/FPGA}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Application}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Application}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Application/Drivers}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Application/Drivers}&quot;"/>
@ -185,6 +187,8 @@
<listOptionValue builtIn="false" value="USE_FULL_LL_DRIVER"/> <listOptionValue builtIn="false" value="USE_FULL_LL_DRIVER"/>
<listOptionValue builtIn="false" value="HW_REVISION='B'"/>
<listOptionValue builtIn="false" value="__weak=&quot;__attribute__((weak))&quot;"/> <listOptionValue builtIn="false" value="__weak=&quot;__attribute__((weak))&quot;"/>
<listOptionValue builtIn="false" value="USBPD_PORT_COUNT=1"/> <listOptionValue builtIn="false" value="USBPD_PORT_COUNT=1"/>

View File

@ -5,12 +5,11 @@
#include "Communication.h" #include "Communication.h"
#include "main.h" #include "main.h"
#include "Exti.hpp" #include "Exti.hpp"
#include "FPGA.hpp" #include "FPGA/FPGA.hpp"
#include <complex> #include <complex>
#include <cstring> #include <cstring>
#include "USB/usb.h" #include "USB/usb.h"
#include "Flash.hpp" #include "Flash.hpp"
#include "Firmware.hpp"
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
@ -28,12 +27,17 @@ static Protocol::PacketInfo packet;
static TaskHandle_t handle; static TaskHandle_t handle;
// TODO set proper values // TODO set proper values
#define HW_REVISION 'A' //#define HW_REVISION 'A'
#define FW_MAJOR 0 #define FW_MAJOR 0
#define FW_MINOR 01 #define FW_MINOR 01
#if HW_REVISION >= 'B'
// has MCU controllable flash chip, firmware update supported
#define HAS_FLASH
#include "Firmware.hpp"
extern SPI_HandleTypeDef hspi1; extern SPI_HandleTypeDef hspi1;
static Flash flash = Flash(&hspi1, FLASH_CS_GPIO_Port, FLASH_CS_Pin); static Flash flash = Flash(&hspi1, FLASH_CS_GPIO_Port, FLASH_CS_Pin);
#endif
#define FLAG_USB_PACKET 0x01 #define FLAG_USB_PACKET 0x01
#define FLAG_DATAPOINT 0x02 #define FLAG_DATAPOINT 0x02
@ -67,6 +71,7 @@ void App_Start() {
Log_SetRedirect(usb_log); Log_SetRedirect(usb_log);
LOG_INFO("Start"); LOG_INFO("Start");
Exti::Init(); Exti::Init();
#ifdef HAS_FLASH
if(!flash.isPresent()) { if(!flash.isPresent()) {
LOG_CRIT("Failed to detect onboard FLASH"); LOG_CRIT("Failed to detect onboard FLASH");
} }
@ -80,10 +85,19 @@ void App_Start() {
} else { } else {
LOG_CRIT("Invalid bitstream/firmware, not configuring FPGA"); LOG_CRIT("Invalid bitstream/firmware, not configuring FPGA");
} }
#else
// The FPGA configures itself from the flash, allow time for this
vTaskDelay(2000);
#endif
if (!VNA::Init()) { if (!VNA::Init()) {
LOG_CRIT("Initialization failed, unable to start"); LOG_CRIT("Initialization failed, unable to start");
} }
#if HW_REVISION == 'A'
// Allow USB enumeration
USB_EN_GPIO_Port->BSRR = USB_EN_Pin;
#endif
uint32_t lastNewPoint = HAL_GetTick(); uint32_t lastNewPoint = HAL_GetTick();
bool sweepActive = false; bool sweepActive = false;
@ -180,25 +194,23 @@ void App_Start() {
manual = packet.manual; manual = packet.manual;
VNA::ConfigureManual(manual, VNAStatusCallback); VNA::ConfigureManual(manual, VNAStatusCallback);
break; break;
#ifdef HAS_FLASH
case Protocol::PacketType::ClearFlash: case Protocol::PacketType::ClearFlash:
FPGA::AbortSweep(); FPGA::AbortSweep();
sweepActive = false; sweepActive = false;
LOG_DEBUG("Erasing FLASH in preparation for firmware update..."); LOG_DEBUG("Erasing FLASH in preparation for firmware update...");
if(flash.eraseChip()) { if(flash.eraseChip()) {
LOG_DEBUG("...FLASH erased") LOG_DEBUG("...FLASH erased")
Protocol::PacketInfo p; Communication::SendWithoutPayload(Protocol::PacketType::Ack);
p.type = Protocol::PacketType::Ack;
Communication::Send(p);
} else { } else {
LOG_ERR("Failed to erase FLASH"); LOG_ERR("Failed to erase FLASH");
Communication::SendWithoutPayload(Protocol::PacketType::Nack);
} }
break; break;
case Protocol::PacketType::FirmwarePacket: case Protocol::PacketType::FirmwarePacket:
LOG_INFO("Writing firmware packet at address %u", packet.firmware.address); LOG_INFO("Writing firmware packet at address %u", packet.firmware.address);
flash.write(packet.firmware.address, sizeof(packet.firmware.data), packet.firmware.data); flash.write(packet.firmware.address, sizeof(packet.firmware.data), packet.firmware.data);
Protocol::PacketInfo p; Communication::SendWithoutPayload(Protocol::PacketType::Ack);
p.type = Protocol::PacketType::Ack;
Communication::Send(p);
break; break;
case Protocol::PacketType::PerformFirmwareUpdate: { case Protocol::PacketType::PerformFirmwareUpdate: {
auto fw_info = Firmware::GetFlashContentInfo(&flash); auto fw_info = Firmware::GetFlashContentInfo(&flash);
@ -209,12 +221,15 @@ void App_Start() {
// Some delay to allow communication to finish // Some delay to allow communication to finish
vTaskDelay(1000); vTaskDelay(1000);
Firmware::PerformUpdate(&flash); Firmware::PerformUpdate(&flash);
// will never get here // should never get here
Communication::SendWithoutPayload(Protocol::PacketType::Nack);
} }
} }
break; break;
#endif
default: default:
// ignore all other packets // this packet type is not supported
Communication::SendWithoutPayload(Protocol::PacketType::Nack);
break; break;
} }
} }

View File

@ -63,3 +63,8 @@ void communication_usb_input(const uint8_t *buf, uint16_t len) {
Communication::Input(buf, len); Communication::Input(buf, len);
} }
bool Communication::SendWithoutPayload(Protocol::PacketType type) {
Protocol::PacketInfo p;
p.type = type;
return Send(p);
}

View File

@ -13,6 +13,7 @@ using Callback = void(*)(Protocol::PacketInfo);
void SetCallback(Callback cb); void SetCallback(Callback cb);
void Input(const uint8_t *buf, uint16_t len); void Input(const uint8_t *buf, uint16_t len);
bool Send(Protocol::PacketInfo packet); bool Send(Protocol::PacketInfo packet);
bool SendWithoutPayload(Protocol::PacketType type);
} }

View File

@ -101,6 +101,7 @@ enum class PacketType : uint8_t {
Ack = 7, Ack = 7,
ClearFlash = 8, ClearFlash = 8,
PerformFirmwareUpdate = 9, PerformFirmwareUpdate = 9,
Nack = 10,
}; };
using PacketInfo = struct _packetinfo { using PacketInfo = struct _packetinfo {

View File

@ -11,13 +11,13 @@ static constexpr uint8_t MaxEntries = 16;
static Entry entries[MaxEntries]; static Entry entries[MaxEntries];
void Exti::Init() { void Exti::Init() {
HAL_NVIC_SetPriority(EXTI0_IRQn, 1, 0); HAL_NVIC_SetPriority(EXTI0_IRQn, 5, 0);
HAL_NVIC_SetPriority(EXTI1_IRQn, 1, 0); HAL_NVIC_SetPriority(EXTI1_IRQn, 5, 0);
HAL_NVIC_SetPriority(EXTI2_IRQn, 1, 0); HAL_NVIC_SetPriority(EXTI2_IRQn, 5, 0);
HAL_NVIC_SetPriority(EXTI3_IRQn, 1, 0); HAL_NVIC_SetPriority(EXTI3_IRQn, 5, 0);
HAL_NVIC_SetPriority(EXTI4_IRQn, 1, 0); HAL_NVIC_SetPriority(EXTI4_IRQn, 5, 0);
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 1, 0); HAL_NVIC_SetPriority(EXTI9_5_IRQn, 5, 0);
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 1, 0); HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn); HAL_NVIC_EnableIRQ(EXTI0_IRQn);
HAL_NVIC_EnableIRQ(EXTI1_IRQn); HAL_NVIC_EnableIRQ(EXTI1_IRQn);
HAL_NVIC_EnableIRQ(EXTI2_IRQn); HAL_NVIC_EnableIRQ(EXTI2_IRQn);

View File

@ -2,42 +2,18 @@
#include "delay.hpp" #include "delay.hpp"
#include "stm.hpp" #include "stm.hpp"
#include "main.h" #include "main.h"
#include "FPGA_HAL.hpp"
#define LOG_LEVEL LOG_LEVEL_DEBUG #define LOG_LEVEL LOG_LEVEL_DEBUG
#define LOG_MODULE "FPGA" #define LOG_MODULE "FPGA"
#include "Log.h" #include "Log.h"
#define FPGA_SPI hspi1
#define CONFIGURATION_SPI hspi2
extern SPI_HandleTypeDef FPGA_SPI, CONFIGURATION_SPI;
using GPIO = struct {
GPIO_TypeDef *gpio;
uint16_t pin;
};
static constexpr GPIO CS = {.gpio = FPGA_CS_GPIO_Port, .pin = FPGA_CS_Pin};
static constexpr GPIO PROGRAM_B = {.gpio = FPGA_PROGRAM_B_GPIO_Port, .pin = FPGA_PROGRAM_B_Pin};
static constexpr GPIO INIT_B = {.gpio = FPGA_INIT_B_GPIO_Port, .pin = FPGA_INIT_B_Pin};
static constexpr GPIO DONE = {.gpio = FPGA_DONE_GPIO_Port, .pin = FPGA_DONE_Pin};
static constexpr GPIO FPGA_RESET = {.gpio = FPGA_RESET_GPIO_Port, .pin = FPGA_RESET_Pin};
static constexpr GPIO AUX1 = {.gpio = FPGA_AUX1_GPIO_Port, .pin = FPGA_AUX1_Pin};
static constexpr GPIO AUX2 = {.gpio = FPGA_AUX2_GPIO_Port, .pin = FPGA_AUX2_Pin};
static constexpr GPIO AUX3 = {.gpio = FPGA_AUX3_GPIO_Port, .pin = FPGA_AUX3_Pin};
static inline void Low(GPIO g) {
g.gpio->BSRR = g.pin << 16;
}
static inline void High(GPIO g) {
g.gpio->BSRR = g.pin;
}
bool isHigh(GPIO g) {
return g.gpio->IDR & g.pin;
}
static FPGA::HaltedCallback halted_cb; static FPGA::HaltedCallback halted_cb;
static uint16_t SysCtrlReg = 0x0000; static uint16_t SysCtrlReg = 0x0000;
static uint16_t ISRMaskReg = 0x0000; static uint16_t ISRMaskReg = 0x0000;
using namespace FPGAHAL;
void WriteRegister(FPGA::Reg reg, uint16_t value) { void WriteRegister(FPGA::Reg reg, uint16_t value) {
uint16_t cmd[2] = {(uint16_t) (0x8000 | (uint16_t) reg), value}; uint16_t cmd[2] = {(uint16_t) (0x8000 | (uint16_t) reg), value};
Low(CS); Low(CS);
@ -46,6 +22,12 @@ void WriteRegister(FPGA::Reg reg, uint16_t value) {
} }
bool FPGA::Configure(Flash *f, uint32_t start_address, uint32_t bitstream_size) { bool FPGA::Configure(Flash *f, uint32_t start_address, uint32_t bitstream_size) {
if(!PROGRAM_B.gpio) {
LOG_WARN("PROGRAM_B not defined, assuming FPGA configures itself in master configuration");
// wait too allow enough time for FPGA configuration
HAL_Delay(2000);
return true;
}
LOG_INFO("Loading bitstream of size %lu...", bitstream_size); LOG_INFO("Loading bitstream of size %lu...", bitstream_size);
Low(PROGRAM_B); Low(PROGRAM_B);
while(isHigh(INIT_B)); while(isHigh(INIT_B));

View File

@ -0,0 +1,43 @@
#pragma once
#include "stm.hpp"
#include "main.h"
#define FPGA_SPI hspi1
#define CONFIGURATION_SPI hspi2
extern SPI_HandleTypeDef FPGA_SPI, CONFIGURATION_SPI;
namespace FPGAHAL {
using GPIO = struct {
GPIO_TypeDef *gpio;
uint16_t pin;
};
static constexpr GPIO CS = {.gpio = FPGA_CS_GPIO_Port, .pin = FPGA_CS_Pin};
static constexpr GPIO PROGRAM_B = {.gpio = FPGA_PROGRAM_B_GPIO_Port, .pin = FPGA_PROGRAM_B_Pin};
static constexpr GPIO INIT_B = {.gpio = FPGA_INIT_B_GPIO_Port, .pin = FPGA_INIT_B_Pin};
static constexpr GPIO DONE = {.gpio = FPGA_DONE_GPIO_Port, .pin = FPGA_DONE_Pin};
static constexpr GPIO FPGA_RESET = {.gpio = FPGA_RESET_GPIO_Port, .pin = FPGA_RESET_Pin};
static constexpr GPIO AUX1 = {.gpio = FPGA_AUX1_GPIO_Port, .pin = FPGA_AUX1_Pin};
static constexpr GPIO AUX2 = {.gpio = FPGA_AUX2_GPIO_Port, .pin = FPGA_AUX2_Pin};
static constexpr GPIO AUX3 = {.gpio = FPGA_AUX3_GPIO_Port, .pin = FPGA_AUX3_Pin};
static inline void Low(GPIO g) {
if(g.gpio) {
g.gpio->BSRR = g.pin << 16;
}
}
static inline void High(GPIO g) {
if(g.gpio) {
g.gpio->BSRR = g.pin;
}
}
bool isHigh(GPIO g) {
if(g.gpio) {
return g.gpio->IDR & g.pin;
} else {
return false;
}
}
}

View File

@ -3,21 +3,15 @@
#include "max2871.hpp" #include "max2871.hpp"
#include "main.h" #include "main.h"
#include "delay.hpp" #include "delay.hpp"
#include "FPGA.hpp" #include "FPGA/FPGA.hpp"
#include <complex> #include <complex>
#include "Exti.hpp" #include "Exti.hpp"
#include "VNA_HAL.hpp"
#define LOG_LEVEL LOG_LEVEL_INFO #define LOG_LEVEL LOG_LEVEL_INFO
#define LOG_MODULE "VNA" #define LOG_MODULE "VNA"
#include "Log.h" #include "Log.h"
extern I2C_HandleTypeDef hi2c2;
extern SPI_HandleTypeDef hspi1;
static Si5351C Si5351 = Si5351C(&hi2c2, 26000000);
static MAX2871 Source = MAX2871(&hspi1, FPGA_CS_GPIO_Port, FPGA_CS_Pin, nullptr, 0, nullptr, 0, nullptr, 0, GPIOB, GPIO_PIN_4);
static MAX2871 LO1 = MAX2871(&hspi1, FPGA_CS_GPIO_Port, FPGA_CS_Pin, nullptr, 0, nullptr, 0, nullptr, 0, GPIOB, GPIO_PIN_4);
static constexpr uint32_t IF1 = 60100000; static constexpr uint32_t IF1 = 60100000;
static constexpr uint32_t IF1_alternate = 57000000; static constexpr uint32_t IF1_alternate = 57000000;
static constexpr uint32_t IF2 = 250000; static constexpr uint32_t IF2 = 250000;
@ -42,6 +36,8 @@ static uint16_t IFTableIndexCnt = 0;
static constexpr uint32_t BandSwitchFrequency = 25000000; static constexpr uint32_t BandSwitchFrequency = 25000000;
using namespace VNAHAL;
static void HaltedCallback() { static void HaltedCallback() {
LOG_DEBUG("Halted before point %d", pointCnt); LOG_DEBUG("Halted before point %d", pointCnt);
// Check if IF table has entry at this point // Check if IF table has entry at this point
@ -59,16 +55,16 @@ static void HaltedCallback() {
/ (settings.points - 1); / (settings.points - 1);
if (frequency < BandSwitchFrequency) { if (frequency < BandSwitchFrequency) {
// need the Si5351 as Source // need the Si5351 as Source
Si5351.SetCLK(0, frequency, Si5351C::PLL::B, Si5351.SetCLK(SiChannel::LowbandSource, frequency, Si5351C::PLL::B,
Si5351C::DriveStrength::mA2); Si5351C::DriveStrength::mA2);
if (pointCnt == 0) { if (pointCnt == 0) {
// First point in sweep, enable CLK // First point in sweep, enable CLK
Si5351.Enable(0); Si5351.Enable(SiChannel::LowbandSource);
FPGA::Disable(FPGA::Periphery::SourceRF); FPGA::Disable(FPGA::Periphery::SourceRF);
} }
} else { } else {
// first sweep point in highband is also halted, disable lowband source // first sweep point in highband is also halted, disable lowband source
Si5351.Disable(0); Si5351.Disable(SiChannel::LowbandSource);
FPGA::Enable(FPGA::Periphery::SourceRF); FPGA::Enable(FPGA::Periphery::SourceRF);
} }
@ -122,8 +118,6 @@ static void FPGA_Interrupt(void*) {
bool VNA::Init() { bool VNA::Init() {
LOG_DEBUG("Initializing..."); LOG_DEBUG("Initializing...");
// Wait for FPGA to finish configuration
Delay::ms(2000);
manualMode = false; manualMode = false;
Si5351.Init(); Si5351.Init();
@ -136,24 +130,25 @@ bool VNA::Init() {
while(!Si5351.Locked(Si5351C::PLL::B)); while(!Si5351.Locked(Si5351C::PLL::B));
// Both MAX2871 get a 100MHz reference // Both MAX2871 get a 100MHz reference
Si5351.SetCLK(2, 100000000, Si5351C::PLL::A, Si5351C::DriveStrength::mA2); Si5351.SetCLK(SiChannel::Source, 100000000, Si5351C::PLL::A, Si5351C::DriveStrength::mA2);
Si5351.Enable(2); Si5351.Enable(SiChannel::Source);
Si5351.SetCLK(3, 100000000, Si5351C::PLL::A, Si5351C::DriveStrength::mA2); Si5351.SetCLK(SiChannel::LO1, 100000000, Si5351C::PLL::A, Si5351C::DriveStrength::mA2);
Si5351.Enable(3); Si5351.Enable(SiChannel::LO1);
// 16MHz FPGA clock // 16MHz FPGA clock
Si5351.SetCLK(7, 16000000, Si5351C::PLL::A, Si5351C::DriveStrength::mA2); Si5351.SetCLK(SiChannel::FPGA, 16000000, Si5351C::PLL::A, Si5351C::DriveStrength::mA2);
Si5351.Enable(7); Si5351.Enable(SiChannel::FPGA);
// 10 MHz external reference clock // TODO reference settings controllable through USB
Si5351.SetCLK(6, 10000000, Si5351C::PLL::A, Si5351C::DriveStrength::mA8); // // 10 MHz external reference clock
Si5351.Enable(6); // Si5351.SetCLK(6, 10000000, Si5351C::PLL::A, Si5351C::DriveStrength::mA8);
// Si5351.Enable(6);
// Generate second LO with Si5351 // Generate second LO with Si5351
Si5351.SetCLK(1, IF1 - IF2, Si5351C::PLL::B, Si5351C::DriveStrength::mA2); Si5351.SetCLK(SiChannel::Port1LO2, IF1 - IF2, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
Si5351.Enable(1); Si5351.Enable(SiChannel::Port1LO2);
Si5351.SetCLK(4, IF1 - IF2, Si5351C::PLL::B, Si5351C::DriveStrength::mA2); Si5351.SetCLK(SiChannel::Port2LO2, IF1 - IF2, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
Si5351.Enable(4); Si5351.Enable(SiChannel::Port2LO2);
Si5351.SetCLK(5, IF1 - IF2, Si5351C::PLL::B, Si5351C::DriveStrength::mA2); Si5351.SetCLK(SiChannel::RefLO2, IF1 - IF2, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
Si5351.Enable(5); Si5351.Enable(SiChannel::RefLO2);
// PLL reset appears to realign phases of clock signals // PLL reset appears to realign phases of clock signals
Si5351.ResetPLL(Si5351C::PLL::B); Si5351.ResetPLL(Si5351C::PLL::B);
@ -301,7 +296,7 @@ bool VNA::ConfigureSweep(Protocol::SweepSettings s, SweepCallback cb) {
IFTable[IFTableIndexCnt].IF1 = used_IF; IFTable[IFTableIndexCnt].IF1 = used_IF;
// Configure LO2 for the changed IF1. This is not necessary right now but it will generate // Configure LO2 for the changed IF1. This is not necessary right now but it will generate
// the correct clock settings // the correct clock settings
Si5351.SetCLK(1, used_IF + IF2, Si5351C::PLL::A, Si5351C::DriveStrength::mA2); Si5351.SetCLK(SiChannel::RefLO2, used_IF + IF2, Si5351C::PLL::A, Si5351C::DriveStrength::mA2);
// store calculated clock configuration for later change // store calculated clock configuration for later change
Si5351.ReadRawCLKConfig(1, IFTable[IFTableIndexCnt].clkconfig); Si5351.ReadRawCLKConfig(1, IFTable[IFTableIndexCnt].clkconfig);
IFTableIndexCnt++; IFTableIndexCnt++;
@ -349,11 +344,11 @@ bool VNA::ConfigureManual(Protocol::ManualControl m, StatusCallback cb) {
FPGA::AbortSweep(); FPGA::AbortSweep();
// Configure lowband source // Configure lowband source
if (m.SourceLowEN) { if (m.SourceLowEN) {
Si5351.SetCLK(0, m.SourceLowFrequency, Si5351C::PLL::B, Si5351.SetCLK(SiChannel::LowbandSource, m.SourceLowFrequency, Si5351C::PLL::B,
(Si5351C::DriveStrength) m.SourceLowPower); (Si5351C::DriveStrength) m.SourceLowPower);
Si5351.Enable(0); Si5351.Enable(SiChannel::LowbandSource);
} else { } else {
Si5351.Disable(0); Si5351.Disable(SiChannel::LowbandSource);
} }
// Configure highband source // Configure highband source
Source.SetFrequency(m.SourceHighFrequency); Source.SetFrequency(m.SourceHighFrequency);
@ -365,19 +360,19 @@ bool VNA::ConfigureManual(Protocol::ManualControl m, StatusCallback cb) {
// Configure LO2 // Configure LO2
if(m.LO2EN) { if(m.LO2EN) {
// Generate second LO with Si5351 // Generate second LO with Si5351
Si5351.SetCLK(1, m.LO2Frequency, Si5351C::PLL::B, Si5351C::DriveStrength::mA2); Si5351.SetCLK(SiChannel::Port1LO2, m.LO2Frequency, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
Si5351.Enable(1); Si5351.Enable(SiChannel::Port1LO2);
Si5351.SetCLK(4, m.LO2Frequency, Si5351C::PLL::B, Si5351C::DriveStrength::mA2); Si5351.SetCLK(SiChannel::Port2LO2, m.LO2Frequency, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
Si5351.Enable(4); Si5351.Enable(SiChannel::Port2LO2);
Si5351.SetCLK(5, m.LO2Frequency, Si5351C::PLL::B, Si5351C::DriveStrength::mA2); Si5351.SetCLK(SiChannel::RefLO2, m.LO2Frequency, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
Si5351.Enable(5); Si5351.Enable(SiChannel::RefLO2);
// PLL reset appears to realign phases of clock signals // PLL reset appears to realign phases of clock signals
Si5351.ResetPLL(Si5351C::PLL::B); Si5351.ResetPLL(Si5351C::PLL::B);
} else { } else {
Si5351.Disable(1); Si5351.Disable(SiChannel::Port1LO2);
Si5351.Disable(4); Si5351.Disable(SiChannel::Port2LO2);
Si5351.Disable(5); Si5351.Disable(SiChannel::RefLO2);
} }
FPGA::WriteMAX2871Default(Source.GetRegisters()); FPGA::WriteMAX2871Default(Source.GetRegisters());

View File

@ -2,7 +2,7 @@
#include <cstdint> #include <cstdint>
#include "Protocol.hpp" #include "Protocol.hpp"
#include "FPGA.hpp" #include "FPGA/FPGA.hpp"
namespace VNA { namespace VNA {

View File

@ -0,0 +1,31 @@
#pragma once
#include "stm.hpp"
#include "Si5351C.hpp"
#include "max2871.hpp"
#include "main.h"
extern I2C_HandleTypeDef hi2c2;
extern SPI_HandleTypeDef hspi1;
namespace VNAHAL {
static Si5351C Si5351 = Si5351C(&hi2c2, 26000000);
static MAX2871 Source = MAX2871(&hspi1, FPGA_CS_GPIO_Port, FPGA_CS_Pin, nullptr, 0, nullptr, 0, nullptr, 0, GPIOB, GPIO_PIN_4);
static MAX2871 LO1 = MAX2871(&hspi1, FPGA_CS_GPIO_Port, FPGA_CS_Pin, nullptr, 0, nullptr, 0, nullptr, 0, GPIOB, GPIO_PIN_4);
// Mapping of the Si5351 channels to PLLs/Mixers
namespace SiChannel {
enum {
Source = 3,
LO1 = 5,
Port2LO2 = 4,
RefLO2 = 1,
Port1LO2 = 2,
LowbandSource = 1,
ReferenceOut = 6,
FPGA = 7,
};
}
}