Repository navigation
Operational reliability: hardware-timed chirp bursts, FPGA heartbeat, and RX/TX synchronization - #183
Open
alvarosamudio wants to merge 6 commits into
Open
alvarosamudio wants to merge 6 commits into
alvarosamudio wants to merge 6 commits into
Conversation
…rtbeat supervision
This was referenced Sep 29, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR addresses three operational reliability issues on the AERIS-10:
delay_us/delay_nsbusy-waits), injecting interrupt jitter into the chirp windows and corrupting Doppler phase coherence. The FPGA already had a hardware-timed chirp controller; the MCU now fires a complete burst with a single toggle.ERROR_FPGA_COMMexisted in the enum but was never triggered). A 1 Hz heartbeat on DIG_7 with automatic recovery was added.Along the way we fixed a latent chirp controller bug that broke every burst after the first, and a scan counter shadowing bug that froze the state shown in the GUI.
Changes by area
FPGA —
9_Firmware/9_2_FPGAplfm_chirp_controller.v— burst fix (latent bug)chirp_counteris reset to 0 on entering DONE.CHIRP_MAXafter the first burst; every subsequent burst ran 48+ long chirps before reaching the GUARD transition (only corrected by the 6-bit wrap at 64). With single-trigger bursts from the MCU, each burst must start at 0: exactly 16 long + 16 short.radar_system_top.v— FPGA heartbeat on DIG_7gpio_dig7(previously reserved, tied low) now toggles at ~1 Hz (27-bit counter inclk_100m, 100 MHz / 50 M = 1 Hz).radar_mode_controller.v+radar_receiver_final.v— gated auto-scanframe_gateport (1-cycle pulse). In mode 01 (auto-scan), the FSM waits inS_IDLEfor the TX gate instead of starting immediately; after frame completion it returns toS_IDLE. The next frame's firstmc_new_chirptoggle only happens on the gate..frame_gate(tx_frame_start)inradar_receiver_final.v— the gate is the TX'snew_chirp_frame(toggle-CDC intoclk_100m).formal/fv_radar_mode_controller.v— formal wrapper updatedframe_gateadded as ananyseqinput; Property 6 changed from "never stalls in S_IDLE" to "starts only with the gate and stays in S_IDLE without it".FPGA testbenches
tb/tb_chirp_contract.v— C7 contract updated: the counter now auto-resets at DONE (previously "holds at CHIRP_MAX"); C7b/C7d verify the per-burst auto-reset. C1 comments updated.tb/tb_radar_mode_controller.v—frame_gatesignal + race-freepulse_gatetask (deassert with#1after the sampling edge, avoiding a race with the DUT's always block); gates pulsed in the mode-01 groups;scan_completecounting moved before the re-gate (the pulse lasts 1-2 cycles andpulse_gateconsumes 3 edges); new Group 17 verifies the gating contract (no scanning without a gate, one frame per gate, no activity between gates, second gate works). A full-scan testbench bug (elevation/azimuth reset on every gate) was fixed in the RTL: the gate only resetschirp_count.tb/tb_radar_receiver_final.v—tx_frame_start(the gate) is now generated independently: an initial pulse after reset release plus a pulse on eachscanningfalling edge (frame end). Why: the previous derivation (from the mode controller's ownchirp_countwrap) was circular with the gate — the RX would never have started.tb/tb_system_e2e.v— G8.3 now verifies gated idle (previously: elevation counter ≥ 1); G9 fires one chirp toggle after reset to generate the gate; G11 restructured with its own reset, short timing, and a single toggle (latency measurement against a gated frame).Golden regenerated —
tb/golden/golden_doppler.memandtb/cosim/rx_final_doppler_out.csv. Why: with the gate, the frame starts ~2 cycles later; the frame content changes and the old golden was stale. Regenerated against the merged receiver chain (including develop'sddc_400m.v). Exact comparison: 2048/2048 within tolerance (±2 LSB), 0 mismatches.Test infrastructure
run_regression.sh—run_testaccepts a per-test timeout (default 120 s); the golden tests now use 480 s. Why: the golden tests simulate ~1.3 ms with a 400 MHz ADC clock under iverilog; the fixed 120 s timeout was insufficient even before this PR (~5.5 min on the dev machine).STM32 firmware —
9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cppexecuteChirpSequence()→ burst mode with hardware timingpulseTXMode()→TR_SOURCE=1(bit 2 of REG_SW_CONTROL 0x031) so the ADAR1000 TR pins control TX/RX; (2) one GPIO toggle starts the whole burst (16 long + guard + 16 short); (3) deterministic wait ofnum_chirps*PRI1 + Guard + num_chirps*PRI2≈ 5.65 ms (not timing-critical: chirp boundaries come from the FPGA); (4)pulseRXMode()→ back to SPI RX (safe idle).runRadarPulseSequence()→runRadarScanStep()(per-burst state machine)m/n/ynow update the globals (local shadowing previously left the GUI stuck at BeamPos:1, Azimuth:1, ChirpCount:1).checkFpgaHeartbeat()— liveness supervision with automatic recoveryERROR_FPGA_COMM(12, inside the critical range 9-13 →Emergency_Stop, because an unresponsive FPGA can leave the PA in an uncontrolled TX state).Verification
make test)Risks / hardware pending
TR_SOURCE=1was validated against the datasheet (REG 0x031, bit 2) and the FPGA wiring (Bank 34, 1.8 V,adar_tr_1..4pins), but final confirmation requires testing on hardware. If the pin override is not active on the bench, pin-based TX/RX switching will not work (the previous SPI-based behavior remains available as a fallback)..github/workflows/ci-tests.ymlis in the local repo but has never executed on the remote; opening this PR will run it for the first time (the full regression takes ~12 min on the dev machine).Commits included
fix(fpga): reset chirp_counter at burst end for correct multi-burst operation(2026-07-03 01:39)feat(fpga): add 1 Hz FPGA heartbeat on DIG_7(2026-07-08 01:16)feat(fpga): gate receiver auto-scan on transmitter frame start(2026-07-13 03:14)test(fpga): update testbenches for gated auto-scan and regenerate golden(2026-07-19 02:13)test(fpga): raise golden test timeout in regression runner(2026-07-25 01:39)feat(mcu): FPGA-timed chirp bursts, responsive scan loop and FPGA heartbeat supervision(2026-08-01 00:46)