fix ADSB RX weak signal on pro (#3282)

This commit is contained in:
qwer123
2026-08-05 16:09:55 +08:00
committed by GitHub
parent a4d91f12ef
commit de30cbfe1b
9 changed files with 571 additions and 267 deletions
+57 -31
View File
@@ -144,6 +144,10 @@ static rf::Direction cached_direction = rf::Direction::Receive;
static bool cached_rf_amp = false;
static int_fast8_t cached_lna_gain = 0;
static int_fast8_t cached_vga_gain = 0;
/* FPGA quarter-rate shift mode currently programmed, in gateware encoding
* (0b00 none / 0b11 up / 0b01 down). The baseband filter width depends on it,
* so ReceiverModel reads it back through get_quarter_shift(). */
static uint8_t cached_quarter_shift = 0;
#endif
void init() {
@@ -182,18 +186,15 @@ void init() {
fpga_set_mode(FPGA_MODE_RX);
// These FPGA registers control DC_BLOCK, Q-Inv, QUARTER SHIFT, and Decimation.
fpga_debug_register_write(FPGA_REG_CTRL, FPGA_CTRL_DC_BLOCK_EN); // DC_BLOCK=1, QUARTER_SHIFT=0, Q_INVERT=0
fpga_debug_register_write(FPGA_REG_DECIM, 0x00); // RX_DECIM=No Decim
// RX Mode: Register 3 is RX Digital Gain. Start with 0dB (no shift).
fpga_debug_register_write(FPGA_REG_RX_DIGITAL_GAIN, FPGA_RX_DEFAULT_DIGITAL_GAIN);
/* RX Mode: Initialize DC Block parameters to standard Praline values.
* 0x04 Width and 0x08 Adapt Rate are typical for 40MHz stability.
*/
fpga_debug_register_write(FPGA_REG_RX_DC_BLOCK_WIDTH, FPGA_RX_DEFAULT_DC_WIDTH);
fpga_debug_register_write(FPGA_REG_RX_DC_ADAPT_RATE, FPGA_RX_DEFAULT_ADAPT_RATE);
/* Boot register state, matching fpga_init() in hackrf/firmware/common/fpga.c:
* DC block on, no PRBS, no external trigger, no quarter shift, TX NCO off.
* The decimation ratio and the quarter shift are programmed later by
* ClockManager::set_sampling_frequency() and set_tuning_frequency(). */
fpga_debug_register_write(FPGA_REG_CTRL, FPGA_CTRL_DC_BLOCK_EN);
fpga_debug_register_write(FPGA_REG_DECIM, 0x00); // RX_DECIM = no decimation
fpga_debug_register_write(FPGA_REG_RX_PSTEP, 0x00); // quarter shift off
fpga_debug_register_write(FPGA_REG_TX_CONTROL, 0x00);
cached_quarter_shift = 0;
ssp1_arbiter.invalidate();
chThdSleepMilliseconds(10); // Let FPGA registers settle
@@ -224,13 +225,13 @@ void set_direction(const rf::Direction new_direction) {
fpga_debug_register_write(FPGA_REG_TX_PHASE_STEP, 0x00);
} else {
fpga_set_mode(FPGA_MODE_RX);
// RX Mode: Ensure NCO is disabled and reset digital gain
fpga_debug_register_write(FPGA_REG_RX_DIGITAL_GAIN, FPGA_RX_DEFAULT_DIGITAL_GAIN);
/* RX Mode: Initialize DC Block parameters to standard Praline values.
* 0x04 Width and 0x08 Adapt Rate are typical for 40MHz stability.
*/
fpga_debug_register_write(FPGA_REG_RX_DC_BLOCK_WIDTH, FPGA_RX_DEFAULT_DC_WIDTH);
fpga_debug_register_write(FPGA_REG_RX_DC_ADAPT_RATE, FPGA_RX_DEFAULT_ADAPT_RATE);
/* RX Mode: DC block on, TX NCO off. The quarter shift is re-applied by
* set_tuning_frequency(); clear it here so a stale TX/RX transition
* cannot leave a rotation programmed with no matching LO offset. */
fpga_debug_register_write(FPGA_REG_CTRL, FPGA_CTRL_DC_BLOCK_EN);
fpga_debug_register_write(FPGA_REG_TX_CONTROL, 0x00);
fpga_debug_register_write(FPGA_REG_RX_PSTEP, 0x00);
cached_quarter_shift = 0;
}
#endif
@@ -309,7 +310,19 @@ bool set_tuning_frequency(const rf::Frequency frequency) {
final_frequency = final_frequency + portapack::persistent_memory::config_freq_rx_correction();
}
#ifdef PRALINE
/* The PRALINE tuning tables offset the analogue passband by a quarter of
* the ADC sample rate and have the FPGA rotate it back to DC, so the
* planner needs to know the AFE rate. See tuning.cpp. */
const uint32_t afe_rate = portapack::clock_manager.get_sampling_frequency()
<< portapack::clock_manager.get_resampling_n();
const auto tuning_config = tuning::config::create(
final_frequency,
afe_rate,
direction == rf::Direction::Transmit);
#else
const auto tuning_config = tuning::config::create(final_frequency);
#endif
if (tuning_config.is_valid()) {
first_if.disable();
@@ -339,6 +352,22 @@ bool set_tuning_frequency(const rf::Frequency frequency) {
LPC_GPIO->CLR[0] = (1 << 13); // SGPIO12 = 0 (Q normal)
}
/* Program the FPGA's quarter-rate shift to match the offset the tuning
* table just applied to the analogue centre frequency. The gateware
* (hackrf/firmware/fpga/top/standard.py) takes both bits from the top
* of register 0x03 (rx_pstep):
* rx_pstep[6] -> quarter_shift.enable
* rx_pstep[7] -> quarter_shift.up
* which is exactly fpga_set_rx_quarter_shift_mode() in
* hackrf/firmware/common/fpga.c: write (mode & 0b11) << 6.
*
* These two settings MUST be programmed together. Tuning off-centre
* without the rotation puts the signal outside the decimation filter's
* passband and it disappears entirely; rotating without the offset
* moves the wanted signal off DC by the same amount. */
cached_quarter_shift = tuning_config.quarter_shift;
fpga_debug_register_write(FPGA_REG_RX_PSTEP, (cached_quarter_shift & 0b11) << 6);
ssp1_arbiter.invalidate();
#else
baseband_cpld.set_invert(mixer_invert ^ baseband_invert);
@@ -469,6 +498,10 @@ int_fast8_t get_cached_lna_gain() {
int_fast8_t get_cached_vga_gain() {
return cached_vga_gain;
}
uint8_t get_cached_quarter_shift() {
return cached_quarter_shift;
}
#endif
namespace first_if {
@@ -570,18 +603,11 @@ void register_write(const size_t register_number, uint32_t value) {
void init() {
fpga_set_mode(FPGA_MODE_RX);
// These FPGA registers control DC_BLOCK, Q-Inv, QUARTER SHIFT, and Decimation.
fpga_debug_register_write(FPGA_REG_CTRL, FPGA_CTRL_DC_BLOCK_EN); // DC_BLOCK=1, QUARTER_SHIFT=0, Q_INVERT=0
fpga_debug_register_write(FPGA_REG_DECIM, 0x00); // RX_DECIM=No Decim
// RX Mode: Register 3 is RX Digital Gain. Start with 0dB (no shift).
fpga_debug_register_write(FPGA_REG_RX_DIGITAL_GAIN, FPGA_RX_DEFAULT_DIGITAL_GAIN);
/* RX Mode: Initialize DC Block parameters to standard Praline values.
* 0x04 Width and 0x08 Adapt Rate are typical for 40MHz stability.
*/
fpga_debug_register_write(FPGA_REG_RX_DC_BLOCK_WIDTH, FPGA_RX_DEFAULT_DC_WIDTH);
fpga_debug_register_write(FPGA_REG_RX_DC_ADAPT_RATE, FPGA_RX_DEFAULT_ADAPT_RATE);
/* Same boot state as fpga_init() in hackrf/firmware/common/fpga.c. */
fpga_debug_register_write(FPGA_REG_CTRL, FPGA_CTRL_DC_BLOCK_EN);
fpga_debug_register_write(FPGA_REG_DECIM, 0x00); // RX_DECIM = no decimation
fpga_debug_register_write(FPGA_REG_RX_PSTEP, 0x00); // quarter shift off
fpga_debug_register_write(FPGA_REG_TX_CONTROL, 0x00);
ssp1_arbiter.invalidate(); // Force arbiter to reconfigure on next transfer
}