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
@@ -125,10 +125,11 @@
// ============================================================================
// Canonical Default Values - SINGLE SOURCE OF TRUTH
// ============================================================================
/* Define the canonical RX defaults in ONE place */
#define FPGA_RX_DEFAULT_DC_WIDTH 0x04 /* Typical for 40MHz stability */
#define FPGA_RX_DEFAULT_ADAPT_RATE 0x08 /* Typical for 40MHz stability */
#define FPGA_RX_DEFAULT_DIGITAL_GAIN 0x00 /* No shift initially */
/* Define the canonical RX defaults in ONE place.
* Matches fpga_init() in hackrf/firmware/common/fpga.c: the gateware only has
* rx_decim and rx_pstep on the RX side, both starting at zero. */
#define FPGA_RX_DEFAULT_DECIM 0x00 /* No decimation initially */
#define FPGA_RX_DEFAULT_PSTEP 0x00 /* No quarter-rate shift initially */
/* Define TX defaults */
#define FPGA_TX_DEFAULT_NCO_CTRL 0x00 /* NCO disabled */
@@ -221,12 +222,13 @@ static bool fpga_cdone_read(void) {
// These functions allow reading/writing FPGA internal registers via SPI.
// The FPGA bitstream implements a simple SPI register interface.
//
// FPGA Register Map:
// Reg 1 (CTRL): DC_BLOCK(b0), QUARTER_SHIFT_EN(b1), QUARTER_SHIFT_UP(b2), PRBS(b6), TRIGGER_EN(b7)
// Reg 2 (RX_DECIM): Decimation ratio [2:0]
// Reg 3 (RX/TX): RX Digital Shift OR TX NCO Control
// Reg 4 (RX_DC_BLOCK_WIDTH/TX_INTERP) [2:0]
// Reg 5 (RX_DC_ADAPT_RATE/TX_PSTEP) [7:0]
// FPGA Register Map (hackrf/firmware/fpga/top/standard.py):
// Reg 1 (CTRL): DC_BLOCK(b0), PRBS(b6), TRIGGER_EN(b7)
// Reg 2 (RX_DECIM): Decimation ratio, log2 [2:0]
// Reg 3 (RX_PSTEP): QUARTER_SHIFT_EN(b6), QUARTER_SHIFT_UP(b7)
// Reg 4 (TX_CTRL): NCO enable (b0)
// Reg 5 (TX_INTRP): Interpolation ratio [2:0]
// Reg 6 (TX_PSTEP): NCO phase step [7:0]
//
// SPI Protocol:
// Read: Send [reg & 0x7F, 0x00, 0x00] -> value in byte 3
@@ -369,22 +371,16 @@ void fpga_rx_enable_dc_block(bool enable) {
}
/* RX Functions with mode assertion */
void fpga_rx_set_digital_gain(uint8_t shift) {
/* Quarter-rate shift, register 0x03 bits [7:6]. Equivalent to
* fpga_set_rx_quarter_shift_mode() in hackrf/firmware/common/fpga.c.
* mode: 0b00 none, 0b11 up, 0b01 down. */
void fpga_rx_set_quarter_shift_mode(uint8_t mode) {
if (current_mode != FPGA_MODE_RX) {
/* Log error or assert - wrong mode! */
return;
}
fpga_register_write(FPGA_REG_SHARED_3, shift & FPGA_RX_GAIN_SHIFT_MASK);
}
void fpga_rx_set_dc_block_width(uint8_t width) {
if (current_mode != FPGA_MODE_RX) return;
fpga_register_write(FPGA_REG_SHARED_4, width & FPGA_RX_DC_WIDTH_MASK);
}
void fpga_rx_set_dc_adapt_rate(uint8_t rate) {
if (current_mode != FPGA_MODE_RX) return;
fpga_register_write(FPGA_REG_SHARED_5, rate);
fpga_register_write(FPGA_REG_RX_PSTEP, (uint8_t)((mode & 0x03) << FPGA_RX_QUARTER_SHIFT_SHIFT));
}
// ============================================================================
@@ -394,12 +390,12 @@ void fpga_rx_set_dc_adapt_rate(uint8_t rate) {
/* TX Functions with mode assertion */
void fpga_tx_set_nco_enable(bool enable) {
if (current_mode != FPGA_MODE_TX) return;
uint8_t val = fpga_register_read(FPGA_REG3_TX_NCO_CTRL);
uint8_t val = fpga_register_read(FPGA_REG_TX_CONTROL);
if (enable)
val |= FPGA_TX_NCO_EN;
else
val &= ~FPGA_TX_NCO_EN;
fpga_register_write(FPGA_REG3_TX_NCO_CTRL, val);
fpga_register_write(FPGA_REG_TX_CONTROL, val);
}
void fpga_tx_set_interpolation(uint8_t ratio) {
@@ -424,17 +420,17 @@ static void fpga_register_init(void) {
current_mode = FPGA_MODE_RX;
fpga_spi_write(FPGA_REG_CTRL, FPGA_CTRL_DC_BLOCK_EN);
fpga_spi_write(FPGA_REG_DECIM, 0x00);
fpga_spi_write(FPGA_REG_SHARED_3, FPGA_RX_DEFAULT_DIGITAL_GAIN);
fpga_spi_write(FPGA_REG_SHARED_4, FPGA_RX_DEFAULT_DC_WIDTH);
fpga_spi_write(FPGA_REG_SHARED_5, FPGA_RX_DEFAULT_ADAPT_RATE);
fpga_spi_write(FPGA_REG_DECIM, FPGA_RX_DEFAULT_DECIM);
fpga_spi_write(FPGA_REG_RX_PSTEP, FPGA_RX_DEFAULT_PSTEP);
fpga_spi_write(FPGA_REG_TX_CONTROL, FPGA_TX_DEFAULT_NCO_CTRL);
fpga_spi_write(FPGA_REG_TX_INTERP, FPGA_TX_DEFAULT_INTERP);
/* Update cache */
fpga_reg_cache[1] = FPGA_CTRL_DC_BLOCK_EN;
fpga_reg_cache[2] = 0x00;
fpga_reg_cache[3] = FPGA_RX_DEFAULT_DIGITAL_GAIN;
fpga_reg_cache[4] = FPGA_RX_DEFAULT_DC_WIDTH;
fpga_reg_cache[5] = FPGA_RX_DEFAULT_ADAPT_RATE;
fpga_reg_cache[2] = FPGA_RX_DEFAULT_DECIM;
fpga_reg_cache[3] = FPGA_RX_DEFAULT_PSTEP;
fpga_reg_cache[4] = FPGA_TX_DEFAULT_NCO_CTRL;
fpga_reg_cache[5] = FPGA_TX_DEFAULT_INTERP;
}
// ============================================================================
@@ -16,10 +16,23 @@ extern "C" {
#ifdef PRALINE
/* RX path (legacy PRALINE software map kept for compatibility) */
#define FPGA_REG_RX_DIGITAL_GAIN 0x03 /* Digital Shift / scaling (RX Mode) */
#define FPGA_REG_RX_DC_BLOCK_WIDTH 0x04 /* Notch filter cutoff (RX Mode) */
#define FPGA_REG_RX_DC_ADAPT_RATE 0x05 /* Settle time/Integration (RX Mode) */
/*
* RX path.
*
* NOTE: the register map below is the one the loaded bitstream actually
* implements. Ground truth is hackrf/firmware/fpga/top/standard.py plus
* hackrf/firmware/common/fpga_regs.def; Mayhem, hackrf_usb and debug_for_adsb
* all load a byte-identical praline_fpga.bin, so that map applies here too.
*
* An earlier "legacy PRALINE software map" claimed register 0x03 was an RX
* digital gain and 0x04/0x05 were DC-block width / adaptation rate. The
* gateware has none of those: 0x03 is rx_pstep (whose top two bits are the
* quarter-rate shift) and 0x04/0x05 are TX registers. Writing the old "RX DC
* width" value of 0x01 to 0x04 actually set tx_ctrl[0] and switched the TX NCO
* on, and every write of the fictional digital gain to 0x03 cleared the
* quarter shift.
*/
#define FPGA_REG_RX_PSTEP 0x03 /* RX phase step; bits [7:6] = quarter shift */
/*
* TX path must match the currently built PRALINE standard gateware in
@@ -43,70 +56,55 @@ typedef enum {
/*
* FPGA Register Addresses
* NOTE:
* The currently loaded PRALINE standard gateware uses:
* 0x01 CTRL
* 0x02 RX_DECIM
* 0x03 RX_DIGITAL_GAIN (RX) / TX_NCO_CTRL (TX)
* 0x04 TX_CTRL
* 0x05 TX_INTRP
* 0x06 TX_PSTEP
*
* From hackrf/firmware/fpga/top/standard.py (spi_regs.add_register):
* 0x01 ctrl 8 bits
* 0x02 rx_decim 3 bits
* 0x03 rx_pstep 8 bits
* 0x04 tx_ctrl 1 bit
* 0x05 tx_intrp 3 bits
* 0x06 tx_pstep 8 bits
*
* There is no RX gain register: rx_decim selects half-band FIR stages
* (hbfir1..hbfir5), which are unity-gain, so there is no CIC bit growth to
* renormalise.
*/
#define FPGA_REG_CTRL 0x01 /* Control register */
#define FPGA_REG_DECIM 0x02 /* RX decimation */
#define FPGA_REG_SHARED_3 0x03 /* Legacy shared register */
#define FPGA_REG_SHARED_4 0x04 /* Legacy shared register */
#define FPGA_REG_SHARED_5 0x05 /* Legacy shared register */
#define FPGA_REG_SHARED_6 0x06 /* TX phase step */
#define FPGA_REG_CTRL 0x01 /* Control register */
#define FPGA_REG_DECIM 0x02 /* RX decimation (log2, bits [2:0]) */
/* 0x03..0x06 are FPGA_REG_RX_PSTEP / FPGA_REG_TX_CONTROL /
* FPGA_REG_TX_INTERP / FPGA_REG_TX_PHASE_STEP, defined above. */
/*
* Register 1 (CTRL) Bit Definitions
* standard.py: ctrl[0] -> dc_block.enable, ctrl[6] -> prbs, ctrl[7] -> trigger_en.
* Nothing else in this register is decoded.
*/
#define FPGA_CTRL_DC_BLOCK_EN (1 << 0) /* DC block enable */
#define FPGA_CTRL_QUARTER_SHIFT_EN (1 << 1) /* Quarter-rate shift enable */
#define FPGA_CTRL_QUARTER_SHIFT_UP (1 << 2) /* Shift direction: 1=up, 0=down */
#define FPGA_CTRL_TX_MODE (1 << 5) /* TX mode indicator (if applicable) */
#define FPGA_CTRL_PRBS_EN (1 << 6) /* PRBS test mode */
#define FPGA_CTRL_TRIGGER_EN (1 << 7) /* External trigger enable */
#define FPGA_CTRL_DC_BLOCK_EN (1 << 0) /* DC block enable */
#define FPGA_CTRL_PRBS_EN (1 << 6) /* PRBS test mode */
#define FPGA_CTRL_TRIGGER_EN (1 << 7) /* External trigger enable */
/*
* Register 3 Dual-Purpose Definitions
* Register 3 (RX_PSTEP) Bit Definitions
* standard.py: rx_pstep[6] -> quarter_shift.enable, rx_pstep[7] -> quarter_shift.up.
* Same encoding as fpga_quarter_shift_mode_t << 6 in hackrf/firmware/common/fpga.c.
*/
/* RX Mode: Digital gain/shift */
#define FPGA_REG3_RX_DIGITAL_GAIN 0x03
#define FPGA_RX_GAIN_SHIFT_MASK 0x0F /* Bits [3:0] - shift amount */
/* Position of that 2-bit field inside rx_pstep, for direct register writes. */
#define FPGA_RX_QUARTER_SHIFT_SHIFT 6
#define FPGA_RX_QUARTER_SHIFT_MASK 0xC0
/* TX Mode: NCO control */
#define FPGA_REG3_TX_NCO_CTRL 0x03
#define FPGA_TX_NCO_EN (1 << 0) /* NCO enable */
#define FPGA_TX_NCO_INVERT (1 << 1) /* Invert spectrum */
/* Mode values, matching fpga_quarter_shift_mode_t in
* hackrf/firmware/common/fpga.h. Pass these to
* fpga_rx_set_quarter_shift_mode(), which shifts them into place. */
#define FPGA_QUARTER_SHIFT_MODE_NONE 0b00
#define FPGA_QUARTER_SHIFT_MODE_UP 0b11
#define FPGA_QUARTER_SHIFT_MODE_DOWN 0b01
/*
* Register 4 Dual-Purpose Definitions
* Register 4 (TX_CTRL) / 5 (TX_INTRP) / 6 (TX_PSTEP) Bit Definitions
*/
/* RX Mode: DC block notch width */
#define FPGA_REG4_RX_DC_WIDTH 0x04
#define FPGA_RX_DC_WIDTH_MASK 0x07 /* Bits [2:0] */
/* TX Mode: Interpolation ratio */
#define FPGA_REG4_TX_INTERP 0x05
#define FPGA_TX_INTERP_MASK 0x07 /* Bits [2:0] */
/*
* Register 5 Dual-Purpose Definitions
*/
/* RX Mode: DC block adaptation rate */
#define FPGA_REG5_RX_DC_RATE 0x05
#define FPGA_RX_DC_RATE_MASK 0xFF /* Bits [7:0] */
/* TX Mode: NCO phase step (frequency) */
#define FPGA_REG5_TX_PHASE_STEP 0x06
#define FPGA_TX_PHASE_STEP_MASK 0xFF /* Bits [7:0] */
/* Export default values so other methods can use them */
#define FPGA_RX_DEFAULT_DIGITAL_GAIN 0x00
#define FPGA_RX_DEFAULT_DC_WIDTH 0x04
#define FPGA_RX_DEFAULT_ADAPT_RATE 0x08
#define FPGA_TX_NCO_EN (1 << 0) /* tx_ctrl[0]: NCO enable */
#define FPGA_TX_INTERP_MASK 0x07 /* tx_intrp bits [2:0] */
#define FPGA_TX_PHASE_STEP_MASK 0xFF /* tx_pstep bits [7:0] */
/*
* Core Functions
@@ -133,9 +131,8 @@ void fpga_register_write(uint8_t reg, uint8_t value);
* RX Mode Functions (only valid when mode == FPGA_MODE_RX)
*/
void fpga_rx_set_decimation(uint8_t ratio);
void fpga_rx_set_digital_gain(uint8_t shift);
void fpga_rx_set_dc_block_width(uint8_t width);
void fpga_rx_set_dc_adapt_rate(uint8_t rate);
/* mode is the gateware encoding: 0b00 none, 0b11 up, 0b01 down. */
void fpga_rx_set_quarter_shift_mode(uint8_t mode);
void fpga_rx_enable_dc_block(bool enable);
/*
@@ -154,12 +151,13 @@ void fpga_tx_set_phase_step(uint8_t step);
* reg: Register number (1-5)
* Returns: Register value, or 0xFF if invalid register
*
* FPGA Register Map:
* Reg 1 (CTRL): DC_BLOCK(b0), QUARTER_SHIFT_EN(b1), QUARTER_SHIFT_UP(b2), PRBS(b6), TRIGGER_EN(b7)
* Reg 2 (RX_DECIM): Decimation ratio [2:0]
* Reg 3 (RX/TX): RX Digital Shift OR TX NCO Control
* Reg 4 (RX_DC_BLOCK_WIDTH/TX_INTERP) [2:0]
* Reg 5 (RX_DC_ADAPT_RATE/TX_PSTEP) [7:0]
* FPGA Register Map (hackrf/firmware/fpga/top/standard.py):
* Reg 1 (CTRL): DC_BLOCK(b0), PRBS(b6), TRIGGER_EN(b7)
* Reg 2 (RX_DECIM): Decimation ratio, log2 [2:0]
* Reg 3 (RX_PSTEP): QUARTER_SHIFT_EN(b6), QUARTER_SHIFT_UP(b7)
* Reg 4 (TX_CTRL): NCO_EN(b0)
* Reg 5 (TX_INTRP): Interpolation ratio, log2 [2:0]
* Reg 6 (TX_PSTEP): NCO phase step [7:0]
*/
uint8_t fpga_debug_register_read(uint8_t reg);