fix: use authoritative tx frame signal for frame sync, consistent ad9523 error path
FPGA-001: The previous fix derived frame boundaries from chirp_counter==0, but that counter comes from plfm_chirp_controller_enhanced which overflows to N (not wrapping at chirps_per_elev). This caused frame pulses only on 6-bit rollover (every 64 chirps) instead of every N chirps. Now wires the CDC-synchronized tx_new_chirp_frame_sync signal from the transmitter into radar_receiver_final, giving correct per-frame timing for any N. STM32-004: Changed ad9523_init() failure path from Error_Handler() to return -1, matching the pattern used by ad9523_setup() and ad9523_status() in the same function. Both halt the system, but return -1 keeps IRQs enabled for diagnostic output.
This commit is contained in:
@@ -1181,8 +1181,8 @@ static int configure_ad9523(void)
|
|||||||
int32_t init_ret = ad9523_init(&init_param);
|
int32_t init_ret = ad9523_init(&init_param);
|
||||||
DIAG("CLK", "ad9523_init() returned %ld", (long)init_ret);
|
DIAG("CLK", "ad9523_init() returned %ld", (long)init_ret);
|
||||||
if (init_ret != 0) {
|
if (init_ret != 0) {
|
||||||
DIAG_ERR("CLK", "ad9523_init() FAILED (ret=%ld) -- calling Error_Handler()", (long)init_ret);
|
DIAG_ERR("CLK", "ad9523_init() FAILED (ret=%ld)", (long)init_ret);
|
||||||
Error_Handler();
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,10 @@ module radar_receiver_final (
|
|||||||
input wire adc_dco_n, // Data Clock Output N (400MHz LVDS)
|
input wire adc_dco_n, // Data Clock Output N (400MHz LVDS)
|
||||||
output wire adc_pwdn,
|
output wire adc_pwdn,
|
||||||
|
|
||||||
// Chirp counter from transmitter (for frame sync and matched filter)
|
// Chirp counter from transmitter (for matched filter indexing)
|
||||||
input wire [5:0] chirp_counter,
|
input wire [5:0] chirp_counter,
|
||||||
|
// Frame-start pulse from transmitter (CDC-synchronized, 1 clk_100m cycle)
|
||||||
|
input wire tx_frame_start,
|
||||||
|
|
||||||
output wire [31:0] doppler_output,
|
output wire [31:0] doppler_output,
|
||||||
output wire doppler_valid,
|
output wire doppler_valid,
|
||||||
@@ -392,30 +394,31 @@ mti_canceller #(
|
|||||||
.mti_first_chirp(mti_first_chirp)
|
.mti_first_chirp(mti_first_chirp)
|
||||||
);
|
);
|
||||||
|
|
||||||
// ========== FRAME SYNC USING chirp_counter ==========
|
// ========== FRAME SYNC FROM TRANSMITTER ==========
|
||||||
reg [5:0] chirp_counter_prev;
|
// [FPGA-001 FIXED] Use the authoritative new_chirp_frame signal from the
|
||||||
|
// transmitter (via plfm_chirp_controller_enhanced), CDC-synchronized to
|
||||||
|
// clk_100m in radar_system_top. Previous code tried to derive frame
|
||||||
|
// boundaries from chirp_counter == 0, but that counter comes from the
|
||||||
|
// transmitter path (plfm_chirp_controller_enhanced) which does NOT wrap
|
||||||
|
// at chirps_per_elev — it overflows to N and only wraps at 6-bit rollover
|
||||||
|
// (64). This caused frame pulses at half the expected rate for N=32.
|
||||||
|
reg tx_frame_start_prev;
|
||||||
reg new_frame_pulse;
|
reg new_frame_pulse;
|
||||||
|
|
||||||
always @(posedge clk or negedge reset_n) begin
|
always @(posedge clk or negedge reset_n) begin
|
||||||
if (!reset_n) begin
|
if (!reset_n) begin
|
||||||
chirp_counter_prev <= 6'd0;
|
tx_frame_start_prev <= 1'b0;
|
||||||
new_frame_pulse <= 1'b0;
|
new_frame_pulse <= 1'b0;
|
||||||
end else begin
|
end else begin
|
||||||
// Default: no pulse
|
|
||||||
new_frame_pulse <= 1'b0;
|
new_frame_pulse <= 1'b0;
|
||||||
|
|
||||||
// [FPGA-001 FIXED] Detect frame boundary when chirp_counter wraps to 0.
|
// Edge detect: tx_frame_start is a toggle-CDC derived pulse that
|
||||||
// The chirp_counter (driven by radar_mode_controller) counts 0..N-1
|
// may be 1 clock wide. Capture rising edge for clean 1-cycle pulse.
|
||||||
// and wraps back to 0 at the start of each new frame. Previous code
|
if (tx_frame_start && !tx_frame_start_prev) begin
|
||||||
// also checked (== host_chirps_per_elev) and (== 2*host_chirps_per_elev)
|
|
||||||
// which were unreachable dead conditions for any N, since the counter
|
|
||||||
// never reaches N. Now works correctly for any chirps_per_elev value.
|
|
||||||
if (chirp_counter != chirp_counter_prev && chirp_counter == 6'd0) begin
|
|
||||||
new_frame_pulse <= 1'b1;
|
new_frame_pulse <= 1'b1;
|
||||||
end
|
end
|
||||||
|
|
||||||
// Store previous value
|
tx_frame_start_prev <= tx_frame_start;
|
||||||
chirp_counter_prev <= chirp_counter;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -481,14 +484,6 @@ always @(posedge clk or negedge reset_n) begin
|
|||||||
`endif
|
`endif
|
||||||
chirps_in_current_frame <= 0;
|
chirps_in_current_frame <= 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
// Monitor chirp counter pattern
|
|
||||||
if (chirp_counter != chirp_counter_prev) begin
|
|
||||||
`ifdef SIMULATION
|
|
||||||
$display("[TOP] chirp_counter: %0d ? %0d",
|
|
||||||
chirp_counter_prev, chirp_counter);
|
|
||||||
`endif
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -505,6 +505,8 @@ radar_receiver_final rx_inst (
|
|||||||
|
|
||||||
// Chirp counter from transmitter (CDC-synchronized from 120 MHz domain)
|
// Chirp counter from transmitter (CDC-synchronized from 120 MHz domain)
|
||||||
.chirp_counter(tx_current_chirp_sync),
|
.chirp_counter(tx_current_chirp_sync),
|
||||||
|
// Frame-start pulse from transmitter (CDC-synchronized toggle→pulse)
|
||||||
|
.tx_frame_start(tx_new_chirp_frame_sync),
|
||||||
|
|
||||||
// ADC Physical Interface
|
// ADC Physical Interface
|
||||||
.adc_d_p(adc_d_p),
|
.adc_d_p(adc_d_p),
|
||||||
|
|||||||
@@ -96,15 +96,31 @@ end
|
|||||||
reg [5:0] chirp_counter;
|
reg [5:0] chirp_counter;
|
||||||
reg mc_new_chirp_prev;
|
reg mc_new_chirp_prev;
|
||||||
|
|
||||||
|
// Frame-start pulse: mirrors the real transmitter's new_chirp_frame signal.
|
||||||
|
// In the real system this fires on IDLE→LONG_CHIRP transitions in the chirp
|
||||||
|
// controller. Here we derive it from the mode controller's chirp_count
|
||||||
|
// wrapping back to 0 (which wraps correctly at cfg_chirps_per_elev).
|
||||||
|
reg tx_frame_start;
|
||||||
|
reg [5:0] rmc_chirp_prev;
|
||||||
|
|
||||||
always @(posedge clk_100m or negedge reset_n) begin
|
always @(posedge clk_100m or negedge reset_n) begin
|
||||||
if (!reset_n) begin
|
if (!reset_n) begin
|
||||||
chirp_counter <= 6'd0;
|
chirp_counter <= 6'd0;
|
||||||
mc_new_chirp_prev <= 1'b0;
|
mc_new_chirp_prev <= 1'b0;
|
||||||
|
tx_frame_start <= 1'b0;
|
||||||
|
rmc_chirp_prev <= 6'd0;
|
||||||
end else begin
|
end else begin
|
||||||
mc_new_chirp_prev <= dut.mc_new_chirp;
|
mc_new_chirp_prev <= dut.mc_new_chirp;
|
||||||
if (dut.mc_new_chirp != mc_new_chirp_prev) begin
|
if (dut.mc_new_chirp != mc_new_chirp_prev) begin
|
||||||
chirp_counter <= chirp_counter + 1;
|
chirp_counter <= chirp_counter + 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// Detect when the internal mode controller's chirp_count wraps to 0
|
||||||
|
tx_frame_start <= 1'b0;
|
||||||
|
if (dut.rmc_chirp_count == 6'd0 && rmc_chirp_prev != 6'd0) begin
|
||||||
|
tx_frame_start <= 1'b1;
|
||||||
|
end
|
||||||
|
rmc_chirp_prev <= dut.rmc_chirp_count;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -128,6 +144,7 @@ radar_receiver_final dut (
|
|||||||
.adc_pwdn(),
|
.adc_pwdn(),
|
||||||
|
|
||||||
.chirp_counter(chirp_counter),
|
.chirp_counter(chirp_counter),
|
||||||
|
.tx_frame_start(tx_frame_start),
|
||||||
|
|
||||||
.doppler_output(doppler_output),
|
.doppler_output(doppler_output),
|
||||||
.doppler_valid(doppler_valid),
|
.doppler_valid(doppler_valid),
|
||||||
|
|||||||
Reference in New Issue
Block a user