mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-07-26 10:38:52 +00:00
8f5b25b10d
* fix clock init and add mayhem tx capacity * aligned external clock and RX config * fix(clock): cap TX interpolation to x16 to prevent doubled waveform speed The TX gateware only implements interpolation factors x1..x16 (tx_intrp 0..4), but the rate search could select n==5 (x32) for very low TX sample rates. That left the AFE/CLK0/CLK1 running at the x32 rate while the FPGA only interpolated by x16, clocking the TX datapath at twice the gateware output rate. Cap afe_rate and _resampling_n to the x16 limit in TX so the clocks stay aligned with the interpolation setting. * fix(praline): source PLL1 from 40MHz GP_CLKIN instead of 12MHz XTAL For the intermediate 90-110MHz PLL1 stepping stage, source PLL1 from GP_CLKIN (Si5351 CLK2/MCU_CLK at 40MHz) giving N=2, M=10, Fclk=100MHz, rather than the on-chip 12MHz XTAL bootstrap path. This matches the non-PRALINE path. Remove the dead commented-out XTAL enable/PLL code. * docs(fpga_bridge): correct register 0x03 description for PRALINE gateware Register 0x03 is RX_DIGITAL_GAIN in RX and TX_NCO_CTRL in TX, not RX_PSTEP. * Fix fpga_tx_set_nco_enable to use FPGA_REG3_TX_NCO_CTRL (0x03)
180 lines
4.9 KiB
C
180 lines
4.9 KiB
C
/*
|
|
* FPGA Bridge Header - PRALINE iCE40 FPGA interface
|
|
*
|
|
* Provides functions for initializing and accessing the FPGA on HackRF Pro (PRALINE).
|
|
*/
|
|
|
|
#ifndef __FPGA_BRIDGE_H__
|
|
#define __FPGA_BRIDGE_H__
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
#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) */
|
|
|
|
/*
|
|
* TX path must match the currently built PRALINE standard gateware in
|
|
* hackrf/firmware/fpga/top/standard.py:
|
|
* 0x04 tx_ctrl
|
|
* 0x05 tx_intrp
|
|
* 0x06 tx_pstep
|
|
*/
|
|
#define FPGA_REG_TX_CONTROL 0x04
|
|
#define FPGA_REG_TX_INTERP 0x05
|
|
#define FPGA_REG_TX_PHASE_STEP 0x06
|
|
|
|
/*
|
|
* FPGA Operating Mode
|
|
*/
|
|
typedef enum {
|
|
FPGA_MODE_OFF = 0,
|
|
FPGA_MODE_RX,
|
|
FPGA_MODE_TX
|
|
} fpga_mode_t;
|
|
|
|
/*
|
|
* 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
|
|
*/
|
|
#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 */
|
|
|
|
/*
|
|
* Register 1 (CTRL) Bit Definitions
|
|
*/
|
|
#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 */
|
|
|
|
/*
|
|
* Register 3 Dual-Purpose Definitions
|
|
*/
|
|
/* RX Mode: Digital gain/shift */
|
|
#define FPGA_REG3_RX_DIGITAL_GAIN 0x03
|
|
#define FPGA_RX_GAIN_SHIFT_MASK 0x0F /* Bits [3:0] - shift amount */
|
|
|
|
/* 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 */
|
|
|
|
/*
|
|
* Register 4 Dual-Purpose 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
|
|
|
|
/*
|
|
* Core Functions
|
|
*/
|
|
|
|
/* Initialize the FPGA - loads bitstream from SPIFI flash
|
|
* Returns: 0 on success, non-zero on failure */
|
|
int fpga_bridge_init(uint8_t* mem_base);
|
|
|
|
/* Set operating mode - MUST be called before using mode-specific functions
|
|
* This ensures registers 3-5 are interpreted correctly */
|
|
void fpga_set_mode(fpga_mode_t mode);
|
|
|
|
/* Get current operating mode */
|
|
fpga_mode_t fpga_get_mode(void);
|
|
|
|
/*
|
|
* Low-Level Register Access (use with caution)
|
|
*/
|
|
uint8_t fpga_register_read(uint8_t reg);
|
|
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);
|
|
void fpga_rx_enable_dc_block(bool enable);
|
|
|
|
/*
|
|
* TX Mode Functions (only valid when mode == FPGA_MODE_TX)
|
|
*/
|
|
void fpga_tx_set_interpolation(uint8_t ratio);
|
|
void fpga_tx_set_nco_enable(bool enable);
|
|
void fpga_tx_set_phase_step(uint8_t step);
|
|
|
|
/*
|
|
* Debug Functions
|
|
*/
|
|
|
|
/*
|
|
* Read an FPGA register via SPI
|
|
* 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]
|
|
*/
|
|
uint8_t fpga_debug_register_read(uint8_t reg);
|
|
|
|
/*
|
|
* Write an FPGA register via SPI
|
|
* reg: Register number (1-5)
|
|
* value: Value to write
|
|
*/
|
|
void fpga_debug_register_write(uint8_t reg, uint8_t value);
|
|
|
|
#endif /* PRALINE */
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* __FPGA_BRIDGE_H__ */
|