From 51806b936cf16ebd7d704c50c6aafef4df625f15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20K=C3=A4berich?= Date: Sat, 9 Jan 2021 21:21:47 +0100 Subject: [PATCH] Halt sweep when USB buffer full --- .../Application/Drivers/USB/usb.c | 6 +++- .../Application/Drivers/USB/usb.h | 1 + Software/VNA_embedded/Application/VNA.cpp | 31 ++++++++++++++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/Software/VNA_embedded/Application/Drivers/USB/usb.c b/Software/VNA_embedded/Application/Drivers/USB/usb.c index e338759..f1f2ff8 100644 --- a/Software/VNA_embedded/Application/Drivers/USB/usb.c +++ b/Software/VNA_embedded/Application/Drivers/USB/usb.c @@ -223,7 +223,7 @@ void usb_init(usbd_recv_callback_t receive_callback) { } bool usb_transmit(const uint8_t *data, uint16_t length) { // attempt to add data to fifo - if(usb_transmit_fifo_level + length > sizeof(usb_transmit_fifo)) { + if(length > usb_available_buffer()) { // data won't fit, abort return false; } @@ -280,3 +280,7 @@ void USB_LP_IRQHandler(void) { HAL_PCD_IRQHandler(&hpcd_USB_FS); } + +uint16_t usb_available_buffer() { + return sizeof(usb_transmit_fifo) - usb_transmit_fifo_level; +} diff --git a/Software/VNA_embedded/Application/Drivers/USB/usb.h b/Software/VNA_embedded/Application/Drivers/USB/usb.h index fa3a3bb..b8e1d14 100644 --- a/Software/VNA_embedded/Application/Drivers/USB/usb.h +++ b/Software/VNA_embedded/Application/Drivers/USB/usb.h @@ -19,6 +19,7 @@ typedef void(*usbd_recv_callback_t)(const uint8_t *buf, uint16_t len); void usb_init(usbd_recv_callback_t receive_callback); bool usb_transmit(const uint8_t *data, uint16_t length); +uint16_t usb_available_buffer(); void usb_log(const char *log, uint16_t length); diff --git a/Software/VNA_embedded/Application/VNA.cpp b/Software/VNA_embedded/Application/VNA.cpp index 760b846..1608579 100644 --- a/Software/VNA_embedded/Application/VNA.cpp +++ b/Software/VNA_embedded/Application/VNA.cpp @@ -12,6 +12,7 @@ #include "FreeRTOS.h" #include "task.h" #include "Util.hpp" +#include "usb.h" #define LOG_LEVEL LOG_LEVEL_INFO #define LOG_MODULE "VNA" @@ -44,6 +45,10 @@ static_assert(alternativePrescaler * alternativeSamplerate == 102400000UL, "alte static constexpr uint16_t alternativePhaseInc = 4096 * HW::IF2 / alternativeSamplerate; static_assert(alternativePhaseInc * alternativeSamplerate == 4096 * HW::IF2, "DFT can not be computed for 2.IF when using alternative samplerate"); +// Constants for USB buffer overflow prevention +static constexpr uint16_t maxPointsBetweenHalts = 40; +static constexpr uint32_t reservedUSBbuffer = maxPointsBetweenHalts * (sizeof(Protocol::Datapoint) + 8 /*USB packet overhead*/); + using namespace HWHAL; bool VNA::Setup(Protocol::SweepSettings s) { @@ -106,6 +111,8 @@ bool VNA::Setup(Protocol::SweepSettings s) { // invalidate first entry of IFTable, preventing switing of 2.LO in halted callback IFTable[0].pointCnt = 0xFFFF; + uint16_t pointsWithoutHalt = 0; + // Transfer PLL configuration to FPGA for (uint16_t i = 0; i < points; i++) { bool harmonic_mixing = false; @@ -187,6 +194,17 @@ bool VNA::Setup(Protocol::SweepSettings s) { IFdeviation, (uint32_t ) (freq / 1000000), (uint32_t ) (freq % 1000000)); } + // halt on regular intervals to prevent USB buffer overflow + if(!needs_halt) { + pointsWithoutHalt++; + if(pointsWithoutHalt > maxPointsBetweenHalts) { + needs_halt = true; + } + } + if(needs_halt) { + pointsWithoutHalt = 0; + } + FPGA::WriteSweepConfig(i, lowband, Source.GetRegisters(), LO1.GetRegisters(), attenuator, freq, FPGA::SettlingTime::us20, FPGA::Samples::SPPRegister, needs_halt); @@ -350,7 +368,18 @@ void VNA::SweepHalted() { adcShifted = false; } - FPGA::ResumeHaltedSweep(); + 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([](){ + while(usb_available_buffer() < reservedUSBbuffer); + FPGA::ResumeHaltedSweep(); + }); + } } void VNA::Stop() {