per-point switching: FPGA and LibreVNA MCU changes
FPGA мастера: порт излучает не в одной стадии, а в блоке подряд идущих — младшие SUBSTAGE_BITS бит счётчика стадий стали положением выходного ключа, старшие выбирают порт. Вынесено в функцию port_excites в Sweep.vhd, новое поле приезжает из свободных битов 8:6 регистра SweepSetup через SPIConfig и top.vhd. Совместимость со стоком строгая: при SUBSTAGE_BITS=0 сдвиг нулевой, а добавленная проверка "порт-стадия выше последней" ничего не меняет, потому что счётчик стадий и так пробегает только 0..STAGES. Ручной режим и анализатор спектра, где STAGES=0, ведут себя ровно как раньше. MCU: у SetupSweep добавлен параметр substage_bits со значением по умолчанию 0, поэтому вызовы из Manual.cpp и SpectrumAnalyzer.cpp не тронуты. VNA.cpp берёт ширину под-стадии из port3Stage — порта 3 у этого железа нет, поле свободно, и формат пакета не меняется. Проверено: GHDL анализирует все три VHDL-файла чисто; новый самопроверяющийся Test_Sweep.vhd прогоняет четыре сценария (сток, два положения, приёмник без излучения, четыре положения) и проверен мутацией — с возвращённым стоковым сравнением сценарии с под-стадиями падают. Обе сборки MCU собираются без ошибок. Битовые позиции сверены сквозь всю цепочку: хост шлёт port3Stage=1 в слове 0x243, MCU пишет регистр 0x7041, FPGA читает SUBSTAGE_BITS=1. Слейвы перепрошивать не нужно: им шлётся порт-стадия 7, которая со счётчиком 0..3 не совпадает и в стоковом сравнении. Исходники теперь опережают лежащие рядом бинарники — предупреждение добавлено в начало reproduce/README.md, хеш README в SHA256SUMS обновлён. Порядок ввода в строй расписан в per_point_switching.md. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+3
-1
@@ -143,12 +143,14 @@ void FPGA::SetSettlingTime(uint16_t us) {
|
||||
WriteRegister(Reg::SettlingTimeHigh, value >> 16);
|
||||
}
|
||||
|
||||
void FPGA::SetupSweep(uint8_t stages, uint8_t port1_stage, uint8_t port2_stage, bool synchronize, bool syncMaster) {
|
||||
void FPGA::SetupSweep(uint8_t stages, uint8_t port1_stage, uint8_t port2_stage, bool synchronize, bool syncMaster, uint8_t substage_bits) {
|
||||
uint16_t value = 0x0000;
|
||||
value |= (uint16_t) (stages & 0x07) << 13;
|
||||
if(synchronize) {
|
||||
value |= 0x1000;
|
||||
}
|
||||
// Bits 11..9 of this register are still unused.
|
||||
value |= (uint16_t) (substage_bits & 0x07) << 6;
|
||||
value |= (port1_stage & 0x07) << 3;
|
||||
value |= (port2_stage & 0x07) << 0;
|
||||
WriteRegister(Reg::SweepSetup, value);
|
||||
|
||||
+5
-1
@@ -110,7 +110,11 @@ void WriteRegister(FPGA::Reg reg, uint16_t value);
|
||||
void SetNumberOfPoints(uint16_t npoints);
|
||||
void SetSamplesPerPoint(uint32_t nsamples);
|
||||
void SetSettlingTime(uint16_t us);
|
||||
void SetupSweep(uint8_t stages, uint8_t port1_stage, uint8_t port2_stage, bool synchronize = false, bool syncMaster = false);
|
||||
// substage_bits is how many LOW bits of the stage counter select the stimulus
|
||||
// switch position instead of the excited port, letting a port excite across a
|
||||
// block of consecutive stages (per-point stimulus switching). Zero, the default,
|
||||
// is the stock layout of exactly one stage per port.
|
||||
void SetupSweep(uint8_t stages, uint8_t port1_stage, uint8_t port2_stage, bool synchronize = false, bool syncMaster = false, uint8_t substage_bits = 0);
|
||||
void Enable(Periphery p, bool enable = true);
|
||||
void Disable(Periphery p);
|
||||
bool IsEnabled(Periphery p);
|
||||
|
||||
+5
-1
@@ -338,7 +338,11 @@ bool VNA::Setup(Protocol::SweepSettings s) {
|
||||
FPGA::Enable(FPGA::Periphery::LO1Chip);
|
||||
FPGA::Enable(FPGA::Periphery::LO1RF);
|
||||
#endif
|
||||
FPGA::SetupSweep(s.stages, s.port1Stage, s.port2Stage, s.syncMode != 0, s.syncMaster);
|
||||
// port3Stage carries the stimulus switch substage width: this hardware has no
|
||||
// port 3, so the field is free, and reusing it keeps the packet layout intact.
|
||||
// A host that does not know about per-point switching leaves it at zero, which
|
||||
// is the stock one-stage-per-port layout.
|
||||
FPGA::SetupSweep(s.stages, s.port1Stage, s.port2Stage, s.syncMode != 0, s.syncMaster, s.port3Stage);
|
||||
Trigger::SetMode((Trigger::Mode) s.syncMode);
|
||||
FPGA::Enable(FPGA::Periphery::PortSwitch);
|
||||
pointCnt = 0;
|
||||
|
||||
Reference in New Issue
Block a user