diff --git a/FPGA/VNA/Sweep.vhd b/FPGA/VNA/Sweep.vhd
index 0becdbb..ff3d517 100644
--- a/FPGA/VNA/Sweep.vhd
+++ b/FPGA/VNA/Sweep.vhd
@@ -101,8 +101,8 @@ begin
LO_REG_1 <= MAX2871_DEF_1(31 downto 15) & CONFIG_DATA(87 downto 76) & "001";
-- LO register 3: VCO selection
LO_REG_3 <= CONFIG_DATA(60 downto 55) & MAX2871_DEF_3(25 downto 3) & "011";
- -- both outputs enabled at -1dbm
- LO_REG_4 <= MAX2871_DEF_4(31 downto 23) & CONFIG_DATA(63 downto 61) & MAX2871_DEF_4(19 downto 9) & "101101100";
+ -- both outputs enabled at +5dbm
+ LO_REG_4 <= MAX2871_DEF_4(31 downto 23) & CONFIG_DATA(63 downto 61) & MAX2871_DEF_4(19 downto 9) & "111111100";
ATTENUATOR <= CONFIG_DATA(46 downto 40);
SOURCE_FILTER <= CONFIG_DATA(89 downto 88);
diff --git a/FPGA/VNA/VNA.gise b/FPGA/VNA/VNA.gise
index ae038b9..e27506d 100644
--- a/FPGA/VNA/VNA.gise
+++ b/FPGA/VNA/VNA.gise
@@ -270,7 +270,7 @@
-
+
@@ -292,7 +292,7 @@
-
+
@@ -301,10 +301,12 @@
-
+
+
+
@@ -315,7 +317,7 @@
-
+
@@ -329,7 +331,7 @@
-
+
@@ -375,7 +377,7 @@
-
+
diff --git a/FPGA/VNA/top.bin b/FPGA/VNA/top.bin
index 0cfcb44..db1dac4 100644
Binary files a/FPGA/VNA/top.bin and b/FPGA/VNA/top.bin differ
diff --git a/Software/PC_Application/.gitignore b/Software/PC_Application/.gitignore
index 6089be0..a9e45de 100644
--- a/Software/PC_Application/.gitignore
+++ b/Software/PC_Application/.gitignore
@@ -71,4 +71,6 @@ Thumbs.db
# --------
*.dll
*.exe
+Application
+
diff --git a/Software/PC_Application/Application b/Software/PC_Application/Application
deleted file mode 100755
index 7eabee1..0000000
Binary files a/Software/PC_Application/Application and /dev/null differ
diff --git a/Software/PC_Application/VNA/vna.cpp b/Software/PC_Application/VNA/vna.cpp
index c24ee7b..d9749c3 100644
--- a/Software/PC_Application/VNA/vna.cpp
+++ b/Software/PC_Application/VNA/vna.cpp
@@ -207,7 +207,7 @@ VNA::VNA(AppWindow *window)
auto dbm = new QDoubleSpinBox();
dbm->setValue(settings.cdbm_excitation * 100);
dbm->setFixedWidth(95);
- dbm->setRange(-42.0, -10.0);
+ dbm->setRange(-100.0, 100.0);
dbm->setSingleStep(0.25);
dbm->setSuffix("dbm");
dbm->setToolTip("Stimulus level");
diff --git a/Software/VNA_embedded/Application/Drivers/USB/usb.c b/Software/VNA_embedded/Application/Drivers/USB/usb.c
index adcad8f..b06eab3 100644
--- a/Software/VNA_embedded/Application/Drivers/USB/usb.c
+++ b/Software/VNA_embedded/Application/Drivers/USB/usb.c
@@ -17,8 +17,11 @@ static uint8_t USBD_Class_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t *USBD_Class_GetFSCfgDesc (uint16_t *length);
static uint8_t *USBD_Class_GetDeviceQualifierDescriptor (uint16_t *length);
-static usbd_callback_t cb;
+static usbd_recv_callback_t cb;
static uint8_t usb_receive_buffer[1024];
+static uint8_t usb_transmit_fifo[4096];
+static uint16_t usb_transmit_read_index = 0;
+static uint16_t usb_transmit_fifo_level = 0;
static bool data_transmission_active = false;
static bool log_transmission_active = true;
@@ -145,17 +148,43 @@ static uint8_t USBD_Class_Setup(USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef
}
return USBD_OK;
}
+
+static bool trigger_next_fifo_transmission() {
+ data_transmission_active = true;
+ uint16_t continous_length = sizeof(usb_transmit_fifo) - usb_transmit_read_index;
+ if(continous_length > usb_transmit_fifo_level) {
+ continous_length = usb_transmit_fifo_level;
+ }
+ if(continous_length > sizeof(usb_transmit_fifo)/ 4) {
+ continous_length = sizeof(usb_transmit_fifo) / 4;
+ }
+ hUsbDeviceFS.ep_in[EP_DATA_IN_ADDRESS & 0x7F].total_length = continous_length;
+ return USBD_LL_Transmit(&hUsbDeviceFS, EP_DATA_IN_ADDRESS, &usb_transmit_fifo[usb_transmit_read_index], continous_length) == USBD_OK;
+}
+
static uint8_t USBD_Class_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) {
// A bulk transfer is complete when the endpoint does on of the following:
// - Has transferred exactly the amount of data expected
// - Transfers a packet with a payload size less than wMaxPacketSize or transfers a zero-length packet
+ if(epnum == (EP_DATA_IN_ADDRESS & 0x7F)) {
+ // transmission of fifo data, mark as empty
+ __disable_irq();
+ usb_transmit_fifo_level -= pdev->ep_in[epnum].total_length;
+ usb_transmit_read_index += pdev->ep_in[epnum].total_length;
+ usb_transmit_read_index %= sizeof(usb_transmit_fifo);
+ __enable_irq();
+ }
if (pdev->ep_in[epnum].total_length
&& !(pdev->ep_in[epnum].total_length % USB_FS_MAX_PACKET_SIZE)) {
pdev->ep_in[epnum].total_length = 0;
USBD_LL_Transmit(pdev, epnum, NULL, 0);
} else {
if(epnum == (EP_DATA_IN_ADDRESS & 0x7F)) {
- data_transmission_active = false;
+ if(usb_transmit_fifo_level > 0) {
+ trigger_next_fifo_transmission();
+ } else {
+ data_transmission_active = false;
+ }
} else {
log_transmission_active = false;
}
@@ -182,30 +211,53 @@ static uint8_t *USBD_Class_GetDeviceQualifierDescriptor(uint16_t *length)
return USBD_DeviceQualifierDesc;
}
-void usb_init(usbd_callback_t callback) {
- cb = callback;
+void usb_init(usbd_recv_callback_t receive_callback) {
+ cb = receive_callback;
USBD_Init(&hUsbDeviceFS, &FS_Desc, 0);
USBD_RegisterClass(&hUsbDeviceFS, &USBD_ClassDriver);
USBD_Start(&hUsbDeviceFS);
- HAL_NVIC_SetPriority(USB_HP_IRQn, 7, 0);
+ HAL_NVIC_SetPriority(USB_HP_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USB_HP_IRQn);
HAL_NVIC_SetPriority(USB_LP_IRQn, 7, 0);
HAL_NVIC_EnableIRQ(USB_LP_IRQn);
}
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)) {
+ // data won't fit, abort
+ return false;
+ }
+ // grab pointer to write position
+ __disable_irq();
+ uint16_t write_index = usb_transmit_read_index + usb_transmit_fifo_level;
+ __enable_irq();
+ write_index %= sizeof(usb_transmit_fifo);
+ // copy the data to the fifo
+ uint16_t continous_length = sizeof(usb_transmit_fifo) - write_index;
+ if(continous_length > length) {
+ // can copy all data at once
+ memcpy(&usb_transmit_fifo[write_index], data, length);
+ } else {
+ // needs to copy two data segments
+ memcpy(&usb_transmit_fifo[write_index], data, continous_length);
+ memcpy(&usb_transmit_fifo[0], data + continous_length, length - continous_length);
+ }
+ // increment fifo level
+ __disable_irq();
+ usb_transmit_fifo_level += length;
+ __enable_irq();
+
static bool first = true;
if(first) {
log_transmission_active = false;
first = false;
}
if(!data_transmission_active) {
- data_transmission_active = true;
- hUsbDeviceFS.ep_in[EP_DATA_IN_ADDRESS & 0x7F].total_length = length;
- return USBD_LL_Transmit(&hUsbDeviceFS, EP_DATA_IN_ADDRESS, (uint8_t*) data, length) == USBD_OK;
+ return trigger_next_fifo_transmission();
} else {
- // already have an ongoing transmission
- return false;
+ // still transmitting, no need to trigger
+ return true;
}
}
diff --git a/Software/VNA_embedded/Application/Drivers/USB/usb.h b/Software/VNA_embedded/Application/Drivers/USB/usb.h
index ab89ae7..fa3a3bb 100644
--- a/Software/VNA_embedded/Application/Drivers/USB/usb.h
+++ b/Software/VNA_embedded/Application/Drivers/USB/usb.h
@@ -15,9 +15,9 @@ extern "C" {
#include
#include
-typedef void(*usbd_callback_t)(const uint8_t *buf, uint16_t len);
+typedef void(*usbd_recv_callback_t)(const uint8_t *buf, uint16_t len);
-void usb_init(usbd_callback_t callback);
+void usb_init(usbd_recv_callback_t receive_callback);
bool usb_transmit(const uint8_t *data, uint16_t length);
void usb_log(const char *log, uint16_t length);
diff --git a/Software/VNA_embedded/Application/Hardware.hpp b/Software/VNA_embedded/Application/Hardware.hpp
index ae90e84..bdbc887 100644
--- a/Software/VNA_embedded/Application/Hardware.hpp
+++ b/Software/VNA_embedded/Application/Hardware.hpp
@@ -6,7 +6,7 @@
namespace HW {
static constexpr uint32_t ADCSamplerate = 800000;
-static constexpr uint32_t IF1 = 60000000;
+static constexpr uint32_t IF1 = 62000000;
static constexpr uint32_t IF2 = 250000;
static constexpr uint32_t LO1_minFreq = 25000000;
static constexpr uint32_t MaxSamples = 130944;
@@ -21,7 +21,7 @@ static constexpr Protocol::DeviceLimits Limits = {
.maxIFBW = ADCSamplerate / MinSamples,
.maxPoints = MaxPoints,
.cdbm_min = -4000,
- .cdbm_max = -1000,
+ .cdbm_max = 0,
.minRBW = (uint32_t) (ADCSamplerate * 2.23f / MaxSamples),
.maxRBW = (uint32_t) (ADCSamplerate * 2.23f / MinSamples),
};
diff --git a/Software/VNA_embedded/Application/VNA.cpp b/Software/VNA_embedded/Application/VNA.cpp
index 686eae5..8072423 100644
--- a/Software/VNA_embedded/Application/VNA.cpp
+++ b/Software/VNA_embedded/Application/VNA.cpp
@@ -22,6 +22,7 @@ static uint16_t pointCnt;
static bool excitingPort1;
static Protocol::Datapoint data;
static bool active = false;
+static bool sourceHighPower;
using IFTableEntry = struct {
uint16_t pointCnt;
@@ -62,14 +63,27 @@ bool VNA::Setup(Protocol::SweepSettings s, SweepCallback cb) {
// has to be one less than actual number of samples
FPGA::SetSamplesPerPoint(samplesPerPoint);
+ // Set level (not very accurate)
+ int16_t cdbm = s.cdbm_excitation;
+ if(cdbm > -1000) {
+ // use higher source power (approx 0dbm with no attenuation)
+ sourceHighPower = true;
+ Source.SetPowerOutA(MAX2871::Power::p5dbm, true);
+ } else {
+ // use lower source power (approx -10dbm with no attenuation)
+ sourceHighPower = false;
+ Source.SetPowerOutA(MAX2871::Power::n4dbm, true);
+ cdbm += 1000;
+ }
uint8_t attenuator;
- if(s.cdbm_excitation >= -1000) {
+ if(cdbm >= 0) {
attenuator = 0;
- } else if (s.cdbm_excitation <= -4175){
+ } else if (cdbm <= -3175){
attenuator = 127;
} else {
- attenuator = (-1000 - s.cdbm_excitation) / 25;
+ attenuator = (-cdbm) / 25;
}
+ FPGA::WriteMAX2871Default(Source.GetRegisters());
uint32_t last_LO2 = HW::IF1 - HW::IF2;
Si5351.SetCLK(SiChannel::Port1LO2, last_LO2, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
@@ -116,12 +130,14 @@ bool VNA::Setup(Protocol::SweepSettings s, SweepCallback cb) {
if (s.suppressPeaks && needs_LO2_shift) {
if (IFTableIndexCnt < IFTableNumEntries) {
// still room in table
- LOG_INFO("Changing 2.LO at point %lu to reach correct 2.IF frequency");
needs_halt = true;
IFTable[IFTableIndexCnt].pointCnt = i;
// Configure LO2 for the changed IF1. This is not necessary right now but it will generate
// the correct clock settings
last_LO2 = actualFirstIF - HW::IF2;
+ LOG_INFO("Changing 2.LO to %lu at point %lu (%lu%06luHz) to reach correct 2.IF frequency",
+ last_LO2, i, (uint32_t ) (freq / 1000000),
+ (uint32_t ) (freq % 1000000));
Si5351.SetCLK(SiChannel::RefLO2, last_LO2,
Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
// store calculated clock configuration for later change
@@ -260,7 +276,7 @@ void VNA::SweepHalted() {
if (frequency < BandSwitchFrequency) {
// need the Si5351 as Source
Si5351.SetCLK(SiChannel::LowbandSource, frequency, Si5351C::PLL::B,
- Si5351C::DriveStrength::mA2);
+ sourceHighPower ? Si5351C::DriveStrength::mA8 : Si5351C::DriveStrength::mA2);
if (pointCnt == 0) {
// First point in sweep, enable CLK
Si5351.Enable(SiChannel::LowbandSource);