From 00f0de43f29ed4bfe60527d3fade443eb8fc1eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20K=C3=A4berich?= Date: Tue, 15 Dec 2020 18:03:29 +0100 Subject: [PATCH] Timeout handling in FPGA communication (better recovery from missing reference) --- Software/PC_Application/Device/device.cpp | 3 +-- Software/VNA_embedded/Application/App.cpp | 19 +++++++++++++++++-- .../Application/Communication/Protocol.cpp | 2 ++ .../Application/Communication/Protocol.hpp | 3 ++- .../VNA_embedded/Application/Hardware.cpp | 14 ++++++++++++++ .../VNA_embedded/Application/Hardware.hpp | 1 + Software/VNA_embedded/Application/Manual.cpp | 13 +++++++++++++ .../Application/SpectrumAnalyzer.cpp | 8 ++++++++ Software/VNA_embedded/Application/VNA.cpp | 4 ---- 9 files changed, 58 insertions(+), 9 deletions(-) diff --git a/Software/PC_Application/Device/device.cpp b/Software/PC_Application/Device/device.cpp index c5fde83..2d68298 100644 --- a/Software/PC_Application/Device/device.cpp +++ b/Software/PC_Application/Device/device.cpp @@ -266,8 +266,7 @@ bool Device::SetManual(Protocol::ManualControl manual) bool Device::SetIdle() { - Protocol::SweepSettings s = {}; - return Configure(s); + return SendCommandWithoutPayload(Protocol::PacketType::SetIdle); } bool Device::SendFirmwareChunk(Protocol::FirmwarePacket &fw) diff --git a/Software/VNA_embedded/Application/App.cpp b/Software/VNA_embedded/Application/App.cpp index da946f7..91025e5 100644 --- a/Software/VNA_embedded/Application/App.cpp +++ b/Software/VNA_embedded/Application/App.cpp @@ -25,6 +25,7 @@ #include "Log.h" static Protocol::PacketInfo recv_packet; +static Protocol::PacketInfo last_measure_packet; // contains the command that started the last measured (replay in case of timeout) static TaskHandle_t handle; #if HW_REVISION >= 'B' @@ -108,11 +109,13 @@ void App_Start() { switch(recv_packet.type) { case Protocol::PacketType::SweepSettings: LOG_INFO("New settings received"); + last_measure_packet = recv_packet; sweepActive = VNA::Setup(recv_packet.settings); Communication::SendWithoutPayload(Protocol::PacketType::Ack); break; case Protocol::PacketType::ManualControl: sweepActive = false; + last_measure_packet = recv_packet; Manual::Setup(recv_packet.manual); Communication::SendWithoutPayload(Protocol::PacketType::Ack); break; @@ -125,13 +128,15 @@ void App_Start() { Communication::SendWithoutPayload(Protocol::PacketType::Ack); break; case Protocol::PacketType::Generator: - sweepActive = false; + sweepActive = true; + last_measure_packet = recv_packet; LOG_INFO("Updating generator setting"); Generator::Setup(recv_packet.generator); Communication::SendWithoutPayload(Protocol::PacketType::Ack); break; case Protocol::PacketType::SpectrumAnalyzerSettings: - sweepActive = false; + sweepActive = true; + last_measure_packet = recv_packet; LOG_INFO("Updating spectrum analyzer settings"); SA::Setup(recv_packet.spectrumSettings); Communication::SendWithoutPayload(Protocol::PacketType::Ack); @@ -142,6 +147,11 @@ void App_Start() { HW::fillDeviceInfo(&p.info); Communication::Send(p); break; + case Protocol::PacketType::SetIdle: + HW::SetMode(HW::Mode::Idle); + sweepActive = false; + Communication::SendWithoutPayload(Protocol::PacketType::Ack); + break; #ifdef HAS_FLASH case Protocol::PacketType::ClearFlash: HW::SetMode(HW::Mode::Idle); @@ -197,5 +207,10 @@ void App_Start() { } } } + if(HW::TimedOut()) { + HW::SetMode(HW::Mode::Idle); + // insert the last received packet (restarts the timed out operation) + USBPacketReceived(last_measure_packet); + } } } diff --git a/Software/VNA_embedded/Application/Communication/Protocol.cpp b/Software/VNA_embedded/Application/Communication/Protocol.cpp index d46e98c..aee91fd 100644 --- a/Software/VNA_embedded/Application/Communication/Protocol.cpp +++ b/Software/VNA_embedded/Application/Communication/Protocol.cpp @@ -590,6 +590,7 @@ uint16_t Protocol::DecodeBuffer(uint8_t *buf, uint16_t len, PacketInfo *info) { case PacketType::RequestDeviceInfo: case PacketType::RequestReceiverCal: case PacketType::RequestSourceCal: + case PacketType::SetIdle: // no payload, nothing to do break; case PacketType::None: @@ -643,6 +644,7 @@ uint16_t Protocol::EncodePacket(const PacketInfo &packet, uint8_t *dest, uint16_ case PacketType::RequestDeviceInfo: case PacketType::RequestSourceCal: case PacketType::RequestReceiverCal: + case PacketType::SetIdle: // no payload, nothing to do break; case PacketType::None: diff --git a/Software/VNA_embedded/Application/Communication/Protocol.hpp b/Software/VNA_embedded/Application/Communication/Protocol.hpp index 1eed075..6b9d9bb 100644 --- a/Software/VNA_embedded/Application/Communication/Protocol.hpp +++ b/Software/VNA_embedded/Application/Communication/Protocol.hpp @@ -4,7 +4,7 @@ namespace Protocol { -static constexpr uint16_t Version = 2; +static constexpr uint16_t Version = 3; // When changing/adding/removing variables from these structs also adjust the decode/encode functions in Protocol.cpp @@ -171,6 +171,7 @@ enum class PacketType : uint8_t { RequestReceiverCal = 17, SourceCalPoint = 18, ReceiverCalPoint = 19, + SetIdle = 20, }; using PacketInfo = struct _packetinfo { diff --git a/Software/VNA_embedded/Application/Hardware.cpp b/Software/VNA_embedded/Application/Hardware.cpp index ad25a2d..116527f 100644 --- a/Software/VNA_embedded/Application/Hardware.cpp +++ b/Software/VNA_embedded/Application/Hardware.cpp @@ -18,6 +18,7 @@ static bool extRefInUse = false; HW::Mode activeMode; static Protocol::ReferenceSettings ref; +static uint32_t lastISR; using namespace HWHAL; @@ -53,6 +54,7 @@ static void ReadComplete(const FPGA::SamplingResult &result) { static void FPGA_Interrupt(void*) { FPGA::InitiateSampleRead(ReadComplete); + lastISR = HAL_GetTick(); } void HW::Work() { @@ -174,6 +176,8 @@ bool HW::Init() { LOG_INFO("Initialized"); FPGA::Enable(FPGA::Periphery::ReadyLED); + + Ref::update(); return true; } @@ -195,6 +199,7 @@ void HW::SetMode(Mode mode) { if(mode != Mode::Idle) { // do a full initialization when switching directly between modes HW::Init(); + lastISR = HAL_GetTick(); } SetIdle(); activeMode = mode; @@ -269,6 +274,15 @@ HW::AmplitudeSettings HW::GetAmplitudeSettings(int16_t cdbm, uint64_t freq, bool return ret; } +bool HW::TimedOut() { + constexpr uint32_t timeout = 1000; + if(activeMode != Mode::Idle && HAL_GetTick() - lastISR > timeout) { + return true; + } else { + return false; + } +} + void HW::fillDeviceInfo(Protocol::DeviceInfo *info, bool updateEvenWhenBusy) { // copy constant default values memcpy(info, &HW::Info, sizeof(HW::Info)); diff --git a/Software/VNA_embedded/Application/Hardware.hpp b/Software/VNA_embedded/Application/Hardware.hpp index a87ea7a..a38c2db 100644 --- a/Software/VNA_embedded/Application/Hardware.hpp +++ b/Software/VNA_embedded/Application/Hardware.hpp @@ -86,6 +86,7 @@ bool Init(); void SetMode(Mode mode); void SetIdle(); void Work(); +bool TimedOut(); using AmplitudeSettings = struct _amplitudeSettings { uint8_t attenuator; diff --git a/Software/VNA_embedded/Application/Manual.cpp b/Software/VNA_embedded/Application/Manual.cpp index 41061f7..9229457 100644 --- a/Software/VNA_embedded/Application/Manual.cpp +++ b/Software/VNA_embedded/Application/Manual.cpp @@ -123,6 +123,19 @@ void Manual::Work() { p.status.refmax = limits.Rmax; HW::GetTemps(&p.status.temp_source, &p.status.temp_LO); Communication::Send(p); + HW::Ref::update(); + Protocol::PacketInfo packet; + packet.type = Protocol::PacketType::DeviceInfo; + // Enable PLL chips for temperature reading + bool srcEn = FPGA::IsEnabled(FPGA::Periphery::SourceChip); + bool LOEn = FPGA::IsEnabled(FPGA::Periphery::LO1Chip); + FPGA::Enable(FPGA::Periphery::SourceChip); + FPGA::Enable(FPGA::Periphery::LO1Chip); + HW::fillDeviceInfo(&packet.info, true); + // restore PLL state + FPGA::Enable(FPGA::Periphery::SourceChip, srcEn); + FPGA::Enable(FPGA::Periphery::LO1Chip, LOEn); + Communication::Send(packet); // Trigger next status update FPGA::StartSweep(); } diff --git a/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp b/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp index 1f76bdd..478b31b 100644 --- a/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp +++ b/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp @@ -373,11 +373,19 @@ void SA::Work() { pointCnt += DFTpoints; } else { pointCnt = 0; + // sweep finished, extract device info + FPGA::Enable(FPGA::Periphery::SourceChip); // needs to enable the chip to get a valid temperature reading + Protocol::PacketInfo packet; + packet.type = Protocol::PacketType::DeviceInfo; + HW::fillDeviceInfo(&packet.info, true); + FPGA::Disable(FPGA::Periphery::SourceChip); + Communication::Send(packet); } } else { // more measurements required for signal ID signalIDstep++; } + HW::Ref::update(); StartNextSample(); } diff --git a/Software/VNA_embedded/Application/VNA.cpp b/Software/VNA_embedded/Application/VNA.cpp index e3c354f..baea37c 100644 --- a/Software/VNA_embedded/Application/VNA.cpp +++ b/Software/VNA_embedded/Application/VNA.cpp @@ -259,10 +259,6 @@ void VNA::Work() { // Compile info packet Protocol::PacketInfo packet; packet.type = Protocol::PacketType::DeviceInfo; - packet.info.FPGA_configured = 1; - packet.info.FW_major = FW_MAJOR; - packet.info.FW_minor = FW_MINOR; - packet.info.HW_Revision = HW_REVISION; HW::fillDeviceInfo(&packet.info, true); Communication::Send(packet); // Start next sweep