mirror of
https://github.com/jankae/LibreVNA.git
synced 2026-04-04 14:07:30 +00:00
WIP: device synchronization
This commit is contained in:
parent
047f6ce981
commit
58918f81c1
90 changed files with 8970 additions and 310 deletions
|
|
@ -19,6 +19,7 @@
|
|||
#include "Generator.hpp"
|
||||
#include "SpectrumAnalyzer.hpp"
|
||||
#include "HW_HAL.hpp"
|
||||
#include "Trigger.hpp"
|
||||
|
||||
#define LOG_LEVEL LOG_LEVEL_INFO
|
||||
#define LOG_MODULE "App"
|
||||
|
|
@ -37,7 +38,10 @@ static bool sweepActive;
|
|||
|
||||
extern ADC_HandleTypeDef hadc1;
|
||||
|
||||
#define FLAG_USB_PACKET 0x01
|
||||
#define FLAG_USB_PACKET 0x01
|
||||
#define FLAG_TRIGGER_OUT_ISR 0x02
|
||||
|
||||
static bool lastReportedTrigger;
|
||||
|
||||
static void USBPacketReceived(const Protocol::PacketInfo &p) {
|
||||
recv_packet = p;
|
||||
|
|
@ -46,6 +50,12 @@ static void USBPacketReceived(const Protocol::PacketInfo &p) {
|
|||
portYIELD_FROM_ISR(woken);
|
||||
}
|
||||
|
||||
static void TriggerOutISR() {
|
||||
BaseType_t woken = false;
|
||||
xTaskNotifyFromISR(handle, FLAG_TRIGGER_OUT_ISR, eSetBits, &woken);
|
||||
portYIELD_FROM_ISR(woken);
|
||||
}
|
||||
|
||||
inline void App_Init() {
|
||||
STM::Init();
|
||||
Delay::Init();
|
||||
|
|
@ -60,6 +70,7 @@ inline void App_Init() {
|
|||
Log_SetRedirect(usb_log);
|
||||
LOG_INFO("Start");
|
||||
Exti::Init();
|
||||
Trigger::Init(TriggerOutISR);
|
||||
#ifdef HAS_FLASH
|
||||
if(!HWHAL::flash.isPresent()) {
|
||||
LOG_CRIT("Failed to detect onboard FLASH");
|
||||
|
|
@ -247,16 +258,60 @@ inline void App_Process() {
|
|||
HW::setAcquisitionFrequencies(recv_packet.acquisitionFrequencySettings);
|
||||
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
|
||||
break;
|
||||
case Protocol::PacketType::SetTrigger:
|
||||
if(Trigger::GetMode() == Trigger::Mode::USB_GUI) {
|
||||
Trigger::SetInput(true);
|
||||
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
|
||||
} else {
|
||||
Communication::SendWithoutPayload(Protocol::PacketType::Nack);
|
||||
}
|
||||
break;
|
||||
case Protocol::PacketType::ClearTrigger:
|
||||
if(Trigger::GetMode() == Trigger::Mode::USB_GUI) {
|
||||
Trigger::SetInput(false);
|
||||
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
|
||||
} else {
|
||||
Communication::SendWithoutPayload(Protocol::PacketType::Nack);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// this packet type is not supported
|
||||
Communication::SendWithoutPayload(Protocol::PacketType::Nack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(notification & FLAG_TRIGGER_OUT_ISR) {
|
||||
// trigger output (from FPGA) changed level
|
||||
bool set = Trigger::GetOutput();
|
||||
switch(Trigger::GetMode()) {
|
||||
case Trigger::Mode::Off:
|
||||
// nothing to do
|
||||
break;
|
||||
case Trigger::Mode::USB_GUI:
|
||||
lastReportedTrigger = set;
|
||||
Communication::SendWithoutPayload(set ? Protocol::PacketType::SetTrigger : Protocol::PacketType::ClearTrigger);
|
||||
break;
|
||||
case Trigger::Mode::ExtRef:
|
||||
if(set) {
|
||||
HWHAL::Si5351.Enable(HWHAL::SiChannel::ReferenceOut);
|
||||
} else {
|
||||
HWHAL::Si5351.Disable(HWHAL::SiChannel::ReferenceOut);
|
||||
}
|
||||
break;
|
||||
case Trigger::Mode::Trigger:
|
||||
// not supported by the hardware, nothing to do
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(HW::TimedOut()) {
|
||||
vTaskDelay(1000);
|
||||
LOG_WARN("Timed out, FPGA status: 0x%04x", FPGA::GetStatus());
|
||||
vTaskDelay(1000);
|
||||
LOG_WARN("Trigger out: %d (last reported: %d), in: %d", (uint8_t) Trigger::GetOutput(), (uint8_t) lastReportedTrigger, (uint8_t) Trigger::GetInput());
|
||||
HW::SetMode(HW::Mode::Idle);
|
||||
// insert the last received packet (restarts the timed out operation)
|
||||
Communication::BlockNextAck();
|
||||
USBPacketReceived(last_measure_packet);
|
||||
}
|
||||
HW::updateDeviceStatus();
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
static uint8_t inputBuffer[1024];
|
||||
uint16_t inputCnt = 0;
|
||||
static uint8_t outputBuffer[1024];
|
||||
|
||||
static Communication::Callback callback = nullptr;
|
||||
static uint8_t blockAcks = 0;
|
||||
|
||||
void Communication::SetCallback(Callback cb) {
|
||||
callback = cb;
|
||||
|
|
@ -66,7 +66,15 @@ void communication_usb_input(const uint8_t *buf, uint16_t len) {
|
|||
}
|
||||
|
||||
bool Communication::SendWithoutPayload(Protocol::PacketType type) {
|
||||
if(type == Protocol::PacketType::Ack && blockAcks) {
|
||||
blockAcks--;
|
||||
return true;
|
||||
}
|
||||
Protocol::PacketInfo p;
|
||||
p.type = type;
|
||||
return Send(p);
|
||||
}
|
||||
|
||||
void Communication::BlockNextAck() {
|
||||
blockAcks++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ using Callback = void(*)(const Protocol::PacketInfo&);
|
|||
void SetCallback(Callback cb);
|
||||
void Input(const uint8_t *buf, uint16_t len);
|
||||
bool Send(const Protocol::PacketInfo &packet);
|
||||
void BlockNextAck();
|
||||
bool SendWithoutPayload(Protocol::PacketType type);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,6 +117,8 @@ uint16_t Protocol::EncodePacket(const PacketInfo &packet, uint8_t *dest, uint16_
|
|||
case PacketType::RequestFrequencyCorrection:
|
||||
case PacketType::RequestAcquisitionFrequencySettings:
|
||||
case PacketType::RequestDeviceStatus:
|
||||
case PacketType::SetTrigger:
|
||||
case PacketType::ClearTrigger:
|
||||
// no payload
|
||||
break;
|
||||
case PacketType::VNADatapoint: payload_size = packet.VNAdatapoint->requiredBufferSize(); break;
|
||||
|
|
|
|||
|
|
@ -331,6 +331,8 @@ enum class PacketType : uint8_t {
|
|||
DeviceStatusV1 = 25,
|
||||
RequestDeviceStatus = 26,
|
||||
VNADatapoint = 27,
|
||||
SetTrigger = 28,
|
||||
ClearTrigger = 29,
|
||||
};
|
||||
|
||||
using PacketInfo = struct _packetinfo {
|
||||
|
|
|
|||
|
|
@ -325,7 +325,6 @@ bool Si5351C::WriteRegisterRange(Reg start, const uint8_t *data, uint8_t len) {
|
|||
bool Si5351C::ExtCLKAvailable() {
|
||||
uint8_t value;
|
||||
ReadRegister(Reg::DeviceStatus, &value);
|
||||
LOG_DEBUG("Device status: 0x%02x", value);
|
||||
if (value & 0x10) {
|
||||
return false;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "Util.hpp"
|
||||
#include "Trigger.hpp"
|
||||
#include <array>
|
||||
|
||||
#define LOG_LEVEL LOG_LEVEL_DEBUG
|
||||
|
|
@ -229,6 +230,7 @@ void SA::Setup(Protocol::SpectrumAnalyzerSettings settings) {
|
|||
FPGA::Enable(FPGA::Periphery::Amplifier, s.trackingGenerator);
|
||||
FPGA::Enable(FPGA::Periphery::Port1Mixer);
|
||||
FPGA::Enable(FPGA::Periphery::Port2Mixer);
|
||||
Trigger::SetMode((Trigger::Mode) s.syncMode);
|
||||
|
||||
if(s.SignalID) {
|
||||
// use different ADC prescalers depending on RBW: For small RBWs, images with the shifted ADC samplerate can be closer to the IF
|
||||
|
|
@ -431,7 +433,9 @@ void SA::Work() {
|
|||
// more measurements required for signal ID
|
||||
signalIDstep++;
|
||||
}
|
||||
HW::Ref::update();
|
||||
if(Trigger::GetMode() != Trigger::Mode::ExtRef) {
|
||||
HW::Ref::update();
|
||||
}
|
||||
StartNextSample();
|
||||
}
|
||||
|
||||
|
|
|
|||
73
Software/VNA_embedded/Application/Trigger.cpp
Normal file
73
Software/VNA_embedded/Application/Trigger.cpp
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#include "Trigger.hpp"
|
||||
|
||||
#include "Drivers/Exti.hpp"
|
||||
#include "main.h"
|
||||
#include "HW_HAL.hpp"
|
||||
#include "Communication/Protocol.hpp"
|
||||
#include "Hardware.hpp"
|
||||
|
||||
static Trigger::Mode mode;
|
||||
static Trigger::CallbackISR callback = nullptr;
|
||||
|
||||
void Trigger::Init(CallbackISR cb) {
|
||||
mode = Mode::Off;
|
||||
callback = cb;
|
||||
Exti::SetCallback(FPGA_TRIGGER_OUT_GPIO_Port, FPGA_TRIGGER_OUT_Pin, Exti::EdgeType::Both, Exti::Pull::Down, [](void*){
|
||||
STM::DispatchToInterrupt(callback);
|
||||
}, nullptr);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void vApplicationIdleHook() {
|
||||
if(mode == Trigger::Mode::ExtRef) {
|
||||
STM::DispatchToInterrupt([](){
|
||||
Trigger::SetInput(HW::Ref::available());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Trigger::SetMode(Mode m) {
|
||||
if(mode == m) {
|
||||
// already in the correct mdoe
|
||||
return;
|
||||
}
|
||||
if(mode == Mode::ExtRef) {
|
||||
// reset reference to default settings
|
||||
HWHAL::Si5351.Disable(HWHAL::SiChannel::ReferenceOut);
|
||||
}
|
||||
mode = m;
|
||||
if(mode == Mode::ExtRef) {
|
||||
// Disable the external reference
|
||||
Protocol::ReferenceSettings s;
|
||||
s.AutomaticSwitch = 0;
|
||||
s.ExtRefOuputFreq = 0;
|
||||
s.UseExternalRef = 0;
|
||||
HW::Ref::set(s);
|
||||
HW::Ref::update();
|
||||
|
||||
HWHAL::Si5351.SetCLK(HWHAL::SiChannel::ReferenceOut, 10000000, Si5351C::PLL::A);
|
||||
if(GetOutput()) {
|
||||
HWHAL::Si5351.Enable(HWHAL::SiChannel::ReferenceOut);
|
||||
} else {
|
||||
HWHAL::Si5351.Disable(HWHAL::SiChannel::ReferenceOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
Trigger::Mode Trigger::GetMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
void Trigger::SetInput(bool high) {
|
||||
if(high) {
|
||||
FPGA_TRIGGER_IN_GPIO_Port->BSRR = FPGA_TRIGGER_IN_Pin;
|
||||
} else {
|
||||
FPGA_TRIGGER_IN_GPIO_Port->BSRR = FPGA_TRIGGER_IN_Pin << 16;
|
||||
}
|
||||
}
|
||||
bool Trigger::GetOutput() {
|
||||
return FPGA_TRIGGER_OUT_GPIO_Port->IDR & FPGA_TRIGGER_OUT_Pin;
|
||||
}
|
||||
bool Trigger::GetInput() {
|
||||
return FPGA_TRIGGER_IN_GPIO_Port->IDR & FPGA_TRIGGER_IN_Pin;
|
||||
}
|
||||
25
Software/VNA_embedded/Application/Trigger.hpp
Normal file
25
Software/VNA_embedded/Application/Trigger.hpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Trigger {
|
||||
|
||||
enum class Mode : uint8_t {
|
||||
Off = 0,
|
||||
USB_GUI = 1,
|
||||
ExtRef = 2,
|
||||
Trigger = 3,
|
||||
};
|
||||
|
||||
using CallbackISR = void(*)(void);
|
||||
|
||||
void Init(CallbackISR cb);
|
||||
|
||||
void SetMode(Mode m);
|
||||
Mode GetMode();
|
||||
|
||||
void SetInput(bool high);
|
||||
bool GetOutput();
|
||||
bool GetInput();
|
||||
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
#include "task.h"
|
||||
#include "Util.hpp"
|
||||
#include "usb.h"
|
||||
#include "Trigger.hpp"
|
||||
#include <cmath>
|
||||
|
||||
#define LOG_LEVEL LOG_LEVEL_INFO
|
||||
|
|
@ -279,6 +280,7 @@ bool VNA::Setup(Protocol::SweepSettings s) {
|
|||
FPGA::Enable(FPGA::Periphery::LO1Chip);
|
||||
FPGA::Enable(FPGA::Periphery::LO1RF);
|
||||
FPGA::SetupSweep(s.stages, s.port1Stage, s.port2Stage, s.syncMode != 0);
|
||||
Trigger::SetMode((Trigger::Mode) s.syncMode);
|
||||
FPGA::Enable(FPGA::Periphery::PortSwitch);
|
||||
pointCnt = 0;
|
||||
stageCnt = 0;
|
||||
|
|
@ -350,7 +352,9 @@ bool VNA::MeasurementDone(const FPGA::SamplingResult &result) {
|
|||
|
||||
void VNA::Work() {
|
||||
// end of sweep
|
||||
HW::Ref::update();
|
||||
if(Trigger::GetMode() != Trigger::Mode::ExtRef) {
|
||||
HW::Ref::update();
|
||||
}
|
||||
// Compile info packet
|
||||
Protocol::PacketInfo packet;
|
||||
packet.type = Protocol::PacketType::DeviceStatusV1;
|
||||
|
|
@ -365,86 +369,87 @@ void VNA::SweepHalted() {
|
|||
if(!active) {
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Halted before point %d", pointCnt);
|
||||
// Check if IF table has entry at this point
|
||||
if (IFTableIndexCnt < IFTableNumEntries && IFTable[IFTableIndexCnt].pointCnt == pointCnt) {
|
||||
Si5351.WriteRawCLKConfig(SiChannel::Port1LO2, IFTable[IFTableIndexCnt].clkconfig);
|
||||
Si5351.WriteRawCLKConfig(SiChannel::Port2LO2, IFTable[IFTableIndexCnt].clkconfig);
|
||||
Si5351.WriteRawCLKConfig(SiChannel::RefLO2, IFTable[IFTableIndexCnt].clkconfig);
|
||||
Si5351.ResetPLL(Si5351C::PLL::B);
|
||||
IFTableIndexCnt++;
|
||||
// PLL reset causes the 2.LO to turn off briefly and then ramp on back, needs delay before next point
|
||||
Delay::us(1300);
|
||||
}
|
||||
uint64_t frequency = getPointFrequency(pointCnt);
|
||||
int16_t power = settings.cdbm_excitation_start
|
||||
+ (settings.cdbm_excitation_stop - settings.cdbm_excitation_start)
|
||||
* pointCnt / (settings.points - 1);
|
||||
bool adcShiftRequired = false;
|
||||
if (frequency < HW::BandSwitchFrequency) {
|
||||
auto driveStrength = fixedPowerLowband;
|
||||
if(!settings.fixedPowerSetting) {
|
||||
auto amplitude = HW::GetAmplitudeSettings(power, frequency, true, false);
|
||||
// attenuator value has already been set in sweep setup
|
||||
driveStrength = amplitude.lowBandPower;
|
||||
}
|
||||
|
||||
// need the Si5351 as Source
|
||||
bool freqSuccess = Si5351.SetCLK(SiChannel::LowbandSource, frequency, Si5351C::PLL::B, driveStrength);
|
||||
static bool lowbandDisabled = false;
|
||||
if (pointCnt == 0) {
|
||||
// First point in sweep, switch to correct source
|
||||
FPGA::Disable(FPGA::Periphery::SourceRF);
|
||||
lowbandDisabled = true;
|
||||
}
|
||||
if(lowbandDisabled && freqSuccess) {
|
||||
// frequency is valid, can enable lowband source now
|
||||
Si5351.Enable(SiChannel::LowbandSource);
|
||||
// Resuming the halted sweep requires I2C bus operations to the Si5355. When trigger synchronization is enabled
|
||||
// in the external reference mode, this might collide with the trigger input check. Instead both these actions
|
||||
// are handled through the STM::DispatchToInterrupt functionality, ensuring that they do not interrupt each other
|
||||
STM::DispatchToInterrupt([](){
|
||||
LOG_DEBUG("Halted before point %d", pointCnt);
|
||||
// Check if IF table has entry at this point
|
||||
if (IFTableIndexCnt < IFTableNumEntries && IFTable[IFTableIndexCnt].pointCnt == pointCnt) {
|
||||
Si5351.WriteRawCLKConfig(SiChannel::Port1LO2, IFTable[IFTableIndexCnt].clkconfig);
|
||||
Si5351.WriteRawCLKConfig(SiChannel::Port2LO2, IFTable[IFTableIndexCnt].clkconfig);
|
||||
Si5351.WriteRawCLKConfig(SiChannel::RefLO2, IFTable[IFTableIndexCnt].clkconfig);
|
||||
Si5351.ResetPLL(Si5351C::PLL::B);
|
||||
IFTableIndexCnt++;
|
||||
// PLL reset causes the 2.LO to turn off briefly and then ramp on back, needs delay before next point
|
||||
Delay::us(1300);
|
||||
lowbandDisabled = false;
|
||||
}
|
||||
|
||||
// At low frequencies the 1.LO feedthrough mixes with the 2.LO in the second mixer.
|
||||
// Depending on the stimulus frequency, the resulting mixing product might alias to the 2.IF
|
||||
// in the ADC which causes a spike. Check for this and shift the ADC sampling frequency if necessary
|
||||
|
||||
uint32_t LO_mixing = (HW::getIF1() + frequency) - (HW::getIF1() - HW::getIF2());
|
||||
if(abs(Util::Alias(LO_mixing, HW::getADCRate()) - HW::getIF2()) <= actualBandwidth * 2) {
|
||||
// the image is in or near the IF bandwidth and would cause a peak
|
||||
// Use a slightly different ADC sample rate if possible
|
||||
if(HW::getIF2() == HW::DefaultIF2) {
|
||||
adcShiftRequired = true;
|
||||
uint64_t frequency = getPointFrequency(pointCnt);
|
||||
int16_t power = settings.cdbm_excitation_start
|
||||
+ (settings.cdbm_excitation_stop - settings.cdbm_excitation_start)
|
||||
* pointCnt / (settings.points - 1);
|
||||
bool adcShiftRequired = false;
|
||||
if (frequency < HW::BandSwitchFrequency) {
|
||||
auto driveStrength = fixedPowerLowband;
|
||||
if(!settings.fixedPowerSetting) {
|
||||
auto amplitude = HW::GetAmplitudeSettings(power, frequency, true, false);
|
||||
// attenuator value has already been set in sweep setup
|
||||
driveStrength = amplitude.lowBandPower;
|
||||
}
|
||||
|
||||
// need the Si5351 as Source
|
||||
bool freqSuccess = Si5351.SetCLK(SiChannel::LowbandSource, frequency, Si5351C::PLL::B, driveStrength);
|
||||
static bool lowbandDisabled = false;
|
||||
if (pointCnt == 0) {
|
||||
// First point in sweep, switch to correct source
|
||||
FPGA::Disable(FPGA::Periphery::SourceRF);
|
||||
lowbandDisabled = true;
|
||||
}
|
||||
if(lowbandDisabled && freqSuccess) {
|
||||
// frequency is valid, can enable lowband source now
|
||||
Si5351.Enable(SiChannel::LowbandSource);
|
||||
Delay::us(1300);
|
||||
lowbandDisabled = false;
|
||||
}
|
||||
|
||||
// At low frequencies the 1.LO feedthrough mixes with the 2.LO in the second mixer.
|
||||
// Depending on the stimulus frequency, the resulting mixing product might alias to the 2.IF
|
||||
// in the ADC which causes a spike. Check for this and shift the ADC sampling frequency if necessary
|
||||
|
||||
uint32_t LO_mixing = (HW::getIF1() + frequency) - (HW::getIF1() - HW::getIF2());
|
||||
if(abs(Util::Alias(LO_mixing, HW::getADCRate()) - HW::getIF2()) <= actualBandwidth * 2) {
|
||||
// the image is in or near the IF bandwidth and would cause a peak
|
||||
// Use a slightly different ADC sample rate if possible
|
||||
if(HW::getIF2() == HW::DefaultIF2) {
|
||||
adcShiftRequired = true;
|
||||
}
|
||||
}
|
||||
} else if(!FPGA::IsEnabled(FPGA::Periphery::SourceRF)){
|
||||
// first sweep point in highband is also halted, disable lowband source
|
||||
Si5351.Disable(SiChannel::LowbandSource);
|
||||
FPGA::Enable(FPGA::Periphery::SourceRF);
|
||||
}
|
||||
} else if(!FPGA::IsEnabled(FPGA::Periphery::SourceRF)){
|
||||
// first sweep point in highband is also halted, disable lowband source
|
||||
Si5351.Disable(SiChannel::LowbandSource);
|
||||
FPGA::Enable(FPGA::Periphery::SourceRF);
|
||||
}
|
||||
|
||||
if (pointCnt == 0) {
|
||||
HAL_Delay(2);
|
||||
}
|
||||
if (pointCnt == 0) {
|
||||
HAL_Delay(2);
|
||||
}
|
||||
|
||||
if(adcShiftRequired) {
|
||||
FPGA::WriteRegister(FPGA::Reg::ADCPrescaler, alternativePrescaler);
|
||||
FPGA::WriteRegister(FPGA::Reg::PhaseIncrement, alternativePhaseInc);
|
||||
adcShifted = true;
|
||||
} else if(adcShifted) {
|
||||
// reset to default value
|
||||
FPGA::WriteRegister(FPGA::Reg::ADCPrescaler, HW::getADCPrescaler());
|
||||
FPGA::WriteRegister(FPGA::Reg::PhaseIncrement, HW::getDFTPhaseInc());
|
||||
adcShifted = false;
|
||||
}
|
||||
if(adcShiftRequired) {
|
||||
FPGA::WriteRegister(FPGA::Reg::ADCPrescaler, alternativePrescaler);
|
||||
FPGA::WriteRegister(FPGA::Reg::PhaseIncrement, alternativePhaseInc);
|
||||
adcShifted = true;
|
||||
} else if(adcShifted) {
|
||||
// reset to default value
|
||||
FPGA::WriteRegister(FPGA::Reg::ADCPrescaler, HW::getADCPrescaler());
|
||||
FPGA::WriteRegister(FPGA::Reg::PhaseIncrement, HW::getDFTPhaseInc());
|
||||
adcShifted = false;
|
||||
}
|
||||
|
||||
if(usb_available_buffer() >= reservedUSBbuffer) {
|
||||
// enough space available, can resume immediately
|
||||
FPGA::ResumeHaltedSweep();
|
||||
} else {
|
||||
// USB buffer could potentially overflow before next halted point, wait until more space is available.
|
||||
// This function is called from a low level interrupt, need to dispatch to lower priority to allow USB
|
||||
// handling to continue
|
||||
STM::DispatchToInterrupt([](){
|
||||
if(usb_available_buffer() >= reservedUSBbuffer) {
|
||||
// enough space available, can resume immediately
|
||||
FPGA::ResumeHaltedSweep();
|
||||
} else {
|
||||
// USB buffer could potentially overflow before next halted point, wait until more space is available.
|
||||
uint32_t start = HAL_GetTick();
|
||||
while(usb_available_buffer() < reservedUSBbuffer) {
|
||||
if(HAL_GetTick() - start > 100) {
|
||||
|
|
@ -457,8 +462,8 @@ void VNA::SweepHalted() {
|
|||
}
|
||||
}
|
||||
FPGA::ResumeHaltedSweep();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void VNA::Stop() {
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
#define configUSE_PREEMPTION 1
|
||||
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 0
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_IDLE_HOOK 1
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configCPU_CLOCK_HZ ( SystemCoreClock )
|
||||
#define configTICK_RATE_HZ ((TickType_t)1000)
|
||||
|
|
|
|||
|
|
@ -89,6 +89,10 @@ void Error_Handler(void);
|
|||
#define FPGA_PROGRAM_B_GPIO_Port GPIOB
|
||||
#define EN_6V_Pin GPIO_PIN_12
|
||||
#define EN_6V_GPIO_Port GPIOB
|
||||
#define FPGA_TRIGGER_OUT_Pin GPIO_PIN_11
|
||||
#define FPGA_TRIGGER_OUT_GPIO_Port GPIOC
|
||||
#define FPGA_TRIGGER_IN_Pin GPIO_PIN_3
|
||||
#define FPGA_TRIGGER_IN_GPIO_Port GPIOB
|
||||
#define FPGA_RESET_Pin GPIO_PIN_5
|
||||
#define FPGA_RESET_GPIO_Port GPIOB
|
||||
#define FPGA_DONE_Pin GPIO_PIN_9
|
||||
|
|
|
|||
|
|
@ -55,6 +55,24 @@
|
|||
/* GetIdleTaskMemory prototype (linked to static allocation support) */
|
||||
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );
|
||||
|
||||
/* Hook prototypes */
|
||||
void vApplicationIdleHook(void);
|
||||
|
||||
/* USER CODE BEGIN 2 */
|
||||
__weak void vApplicationIdleHook( void )
|
||||
{
|
||||
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
|
||||
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
|
||||
task. It is essential that code added to this hook function never attempts
|
||||
to block in any way (for example, call xQueueReceive() with a block time
|
||||
specified, or call vTaskDelay()). If the application makes use of the
|
||||
vTaskDelete() API function (as this demo application does) then it is also
|
||||
important that vApplicationIdleHook() is permitted to return to its calling
|
||||
function, because it is the responsibility of the idle task to clean up
|
||||
memory allocated by the kernel to any task that has since been deleted. */
|
||||
}
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */
|
||||
static StaticTask_t xIdleTaskTCBBuffer;
|
||||
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];
|
||||
|
|
|
|||
|
|
@ -724,7 +724,7 @@ static void MX_GPIO_Init(void)
|
|||
HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_SET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOB, FPGA_PROGRAM_B_Pin|EN_6V_Pin|FPGA_RESET_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOB, FPGA_PROGRAM_B_Pin|EN_6V_Pin|FPGA_TRIGGER_IN_Pin|FPGA_RESET_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin : FPGA_INIT_B_Pin */
|
||||
GPIO_InitStruct.Pin = FPGA_INIT_B_Pin;
|
||||
|
|
@ -752,13 +752,19 @@ static void MX_GPIO_Init(void)
|
|||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(FPGA_INTR_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : FPGA_PROGRAM_B_Pin EN_6V_Pin FPGA_RESET_Pin */
|
||||
GPIO_InitStruct.Pin = FPGA_PROGRAM_B_Pin|EN_6V_Pin|FPGA_RESET_Pin;
|
||||
/*Configure GPIO pins : FPGA_PROGRAM_B_Pin EN_6V_Pin FPGA_TRIGGER_IN_Pin FPGA_RESET_Pin */
|
||||
GPIO_InitStruct.Pin = FPGA_PROGRAM_B_Pin|EN_6V_Pin|FPGA_TRIGGER_IN_Pin|FPGA_RESET_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : FPGA_TRIGGER_OUT_Pin */
|
||||
GPIO_InitStruct.Pin = FPGA_TRIGGER_OUT_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
|
||||
HAL_GPIO_Init(FPGA_TRIGGER_OUT_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : FPGA_DONE_Pin */
|
||||
GPIO_InitStruct.Pin = FPGA_DONE_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
|
|
|
|||
|
|
@ -86,14 +86,16 @@ FREERTOS.INCLUDE_vTaskDelete=0
|
|||
FREERTOS.INCLUDE_vTaskPrioritySet=0
|
||||
FREERTOS.INCLUDE_vTaskSuspend=1
|
||||
FREERTOS.INCLUDE_xTaskResumeFromISR=0
|
||||
FREERTOS.IPParameters=Tasks01,INCLUDE_vTaskDelete,INCLUDE_vTaskPrioritySet,INCLUDE_uxTaskPriorityGet,INCLUDE_xTaskResumeFromISR,INCLUDE_vTaskSuspend,MEMORY_ALLOCATION,configTOTAL_HEAP_SIZE,configENABLE_BACKWARD_COMPATIBILITY,configUSE_MUTEXES,FootprintOK,configUSE_NEWLIB_REENTRANT
|
||||
FREERTOS.IPParameters=Tasks01,INCLUDE_vTaskDelete,INCLUDE_vTaskPrioritySet,INCLUDE_uxTaskPriorityGet,INCLUDE_xTaskResumeFromISR,INCLUDE_vTaskSuspend,MEMORY_ALLOCATION,configTOTAL_HEAP_SIZE,configENABLE_BACKWARD_COMPATIBILITY,configUSE_MUTEXES,FootprintOK,configUSE_NEWLIB_REENTRANT,configUSE_IDLE_HOOK
|
||||
FREERTOS.MEMORY_ALLOCATION=1
|
||||
FREERTOS.Tasks01=defaultTask,0,1024,StartDefaultTask,Default,NULL,Static,defaultTaskBuffer,defaultTaskControlBlock
|
||||
FREERTOS.configENABLE_BACKWARD_COMPATIBILITY=1
|
||||
FREERTOS.configTOTAL_HEAP_SIZE=2048
|
||||
FREERTOS.configUSE_IDLE_HOOK=1
|
||||
FREERTOS.configUSE_MUTEXES=1
|
||||
FREERTOS.configUSE_NEWLIB_REENTRANT=1
|
||||
File.Version=6
|
||||
GPIO.groupedBy=Group By Peripherals
|
||||
I2C2.I2C_Speed_Mode=I2C_Fast
|
||||
I2C2.IPParameters=Timing,I2C_Speed_Mode
|
||||
I2C2.Timing=0x00F07BFF
|
||||
|
|
@ -134,24 +136,26 @@ Mcu.Pin21=PA13
|
|||
Mcu.Pin22=PA14
|
||||
Mcu.Pin23=PA15
|
||||
Mcu.Pin24=PC10
|
||||
Mcu.Pin25=PB4
|
||||
Mcu.Pin26=PB5
|
||||
Mcu.Pin27=PB6
|
||||
Mcu.Pin28=PB9
|
||||
Mcu.Pin29=VP_ADC1_TempSens_Input
|
||||
Mcu.Pin25=PC11
|
||||
Mcu.Pin26=PB3
|
||||
Mcu.Pin27=PB4
|
||||
Mcu.Pin28=PB5
|
||||
Mcu.Pin29=PB6
|
||||
Mcu.Pin3=PA3
|
||||
Mcu.Pin30=VP_FREERTOS_VS_CMSIS_V1
|
||||
Mcu.Pin31=VP_SYS_VS_tim17
|
||||
Mcu.Pin32=VP_SYS_VS_DBSignals
|
||||
Mcu.Pin33=VP_TIM1_VS_ClockSourceINT
|
||||
Mcu.Pin34=VP_TIM2_VS_ClockSourceINT
|
||||
Mcu.Pin30=PB9
|
||||
Mcu.Pin31=VP_ADC1_TempSens_Input
|
||||
Mcu.Pin32=VP_FREERTOS_VS_CMSIS_V1
|
||||
Mcu.Pin33=VP_SYS_VS_tim17
|
||||
Mcu.Pin34=VP_SYS_VS_DBSignals
|
||||
Mcu.Pin35=VP_TIM1_VS_ClockSourceINT
|
||||
Mcu.Pin36=VP_TIM2_VS_ClockSourceINT
|
||||
Mcu.Pin4=PA4
|
||||
Mcu.Pin5=PA5
|
||||
Mcu.Pin6=PA6
|
||||
Mcu.Pin7=PA7
|
||||
Mcu.Pin8=PC4
|
||||
Mcu.Pin9=PB0
|
||||
Mcu.PinsNb=35
|
||||
Mcu.PinsNb=37
|
||||
Mcu.ThirdPartyNb=0
|
||||
Mcu.UserConstants=
|
||||
Mcu.UserName=STM32G431CBUx
|
||||
|
|
@ -270,6 +274,10 @@ PB2.GPIOParameters=GPIO_Label
|
|||
PB2.GPIO_Label=FPGA_PROGRAM_B
|
||||
PB2.Locked=true
|
||||
PB2.Signal=GPIO_Output
|
||||
PB3.GPIOParameters=GPIO_Label
|
||||
PB3.GPIO_Label=FPGA_TRIGGER_IN
|
||||
PB3.Locked=true
|
||||
PB3.Signal=GPIO_Output
|
||||
PB4.Locked=true
|
||||
PB4.Mode=Sink_AllSignals
|
||||
PB4.Signal=UCPD1_CC2
|
||||
|
|
@ -287,6 +295,11 @@ PB9.Signal=GPIO_Input
|
|||
PC10.Locked=true
|
||||
PC10.Mode=Asynchronous
|
||||
PC10.Signal=USART3_TX
|
||||
PC11.GPIOParameters=GPIO_PuPd,GPIO_Label
|
||||
PC11.GPIO_Label=FPGA_TRIGGER_OUT
|
||||
PC11.GPIO_PuPd=GPIO_PULLDOWN
|
||||
PC11.Locked=true
|
||||
PC11.Signal=GPIO_Input
|
||||
PC4.GPIOParameters=GPIO_Pu
|
||||
PC4.GPIO_Pu=GPIO_PULLUP
|
||||
PC4.Locked=true
|
||||
|
|
@ -311,7 +324,7 @@ ProjectManager.FreePins=false
|
|||
ProjectManager.HalAssertFull=false
|
||||
ProjectManager.HeapSize=0x200
|
||||
ProjectManager.KeepUserCode=true
|
||||
ProjectManager.LastFirmware=true
|
||||
ProjectManager.LastFirmware=false
|
||||
ProjectManager.LibraryCopy=1
|
||||
ProjectManager.MainLocation=Src
|
||||
ProjectManager.NoMain=false
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue