h1r9: implement additional MAX2839 functions, change some mreg definition names, fix RF gain control math

This commit is contained in:
grvvy
2022-09-14 12:49:45 -06:00
committed by Mike Walters
parent cbbe94c8fe
commit 14183a96ea
2 changed files with 91 additions and 39 deletions

View File

@ -56,11 +56,6 @@ static const uint16_t max2839_regs_default[MAX2839_NUM_REGS] = {
0x155, /* 18 */
0x153, /* 19 */
0x249, /* 20 */
/*
* Charge Pump Common Mode Enable bit (0) of register 21 must be set or TX
* does not work. Page 1 of the SPI doc says not to set it (0x02c), but
* page 21 says it should be set by default (0x02d).
*/
0x02d, /* 21 */
0x1a9, /* 22 */
0x24f, /* 23 */
@ -83,7 +78,7 @@ static void max2839_init(max2839_driver_t* const drv)
drv->regs_dirty = 0xffffffff;
/* Write default register values to chip. */
max2837_regs_commit(drv);
max2839_regs_commit(drv);
}
/*
@ -152,35 +147,85 @@ max2839_mode_t max2839_mode(max2839_driver_t* const drv)
void max2839_start(max2839_driver_t* const drv)
{
set_MAX2839_EN_SPI(drv, 1);
set_MAX2839_chip_enable(drv, 1);
max2839_regs_commit(drv);
max2839_set_mode(drv, MAX2839_MODE_STANDBY);
}
void max2839_tx(max2839_driver_t* const drv)
{
// TODO
set_MAX2839_LPFblock_MODE(drv, MAX2839_ModeCtrl_TxLPF);
max2839_regs_commit(drv);
max2839_set_mode(drv, MAX2839_MODE_TX);
}
void max2839_rx(max2839_driver_t* const drv)
{
// TODO
set_MAX2839_LPFblock_MODE(drv, MAX2839_ModeCtrl_RxLPF);
max2839_regs_commit(drv);
max2839_set_mode(drv, MAX2839_MODE_RX);
}
void max2839_stop(max2839_driver_t* const drv)
{
// TODO
set_MAX2839_chip_enable(drv, 0);
max2839_regs_commit(drv);
max2839_set_mode(drv, MAX2839_MODE_SHUTDOWN);
}
void max2839_set_frequency(max2839_driver_t* const drv, uint32_t freq)
{
// TODO
uint8_t band;
uint8_t lna_band;
uint32_t div_frac;
uint32_t div_int;
uint32_t div_rem;
uint32_t div_cmp;
int i;
/* Select band. Allow tuning outside specified bands. */
if (freq < 2400000000U) {
band = MAX2839_LOGEN_BSW_2_3;
lna_band = MAX2839_LNAband_2_4;
} else if (freq < 2500000000U) {
band = MAX2839_LOGEN_BSW_2_4;
lna_band = MAX2839_LNAband_2_4;
} else if (freq < 2600000000U) {
band = MAX2839_LOGEN_BSW_2_5;
lna_band = MAX2839_LNAband_2_6;
} else {
band = MAX2839_LOGEN_BSW_2_6;
lna_band = MAX2839_LNAband_2_6;
}
/* ASSUME 40MHz PLL. Ratio = F*(4/3)/40,000,000 = F/30,000,000 */
div_int = freq / 30000000;
div_rem = freq % 30000000;
div_frac = 0;
div_cmp = 30000000;
for (i = 0; i < 20; i++) {
div_frac <<= 1;
div_cmp >>= 1;
if (div_rem > div_cmp) {
div_frac |= 0x1;
div_rem -= div_cmp;
}
}
/* Band settings */
set_MAX2839_LOGEN_BSW(drv, band);
set_MAX2839_LNAband(drv, lna_band);
/* Write order matters here, so commit INT and FRAC_HI before
* committing FRAC_LO, which is the trigger for VCO
* auto-select. TODO - it's cleaner this way, but it would be
* faster to explicitly commit the registers explicitly so the
* dirty bits aren't scanned twice. */
set_MAX2839_SYN_INT(drv, div_int);
set_MAX2839_SYN_FRAC_HI(drv, (div_frac >> 10) & 0x3ff);
max2839_regs_commit(drv);
set_MAX2839_SYN_FRAC_LO(drv, div_frac & 0x3ff);
max2839_regs_commit(drv);
}
typedef struct {
@ -229,25 +274,27 @@ uint32_t max2839_set_lpf_bandwidth(max2839_driver_t* const drv, const uint32_t b
bool max2839_set_lna_gain(max2839_driver_t* const drv, const uint32_t gain_db) {
uint16_t val;
// TODO: validate steps here
switch(gain_db){
case 40:
val = MAX2839_LNAgain_MAX;
val = MAX2839_LNA1gain_MAX;
break;
case 32:
val = MAX2839_LNAgain_M8;
val = MAX2839_LNA1gain_M8;
break;
case 24:
val = MAX2839_LNAgain_M16;
val = MAX2839_LNA1gain_M16;
break;
case 8:
val = MAX2839_LNAgain_M32;
val = MAX2839_LNA1gain_M32;
break;
case 0:
val = MAX2839_LNA1gain_M32;
break;
default:
return false;
}
set_MAX2839_LNAgain(drv, val);
max2839_reg_commit(drv, 1);
set_MAX2839_LNA1gain(drv, val);
max2839_reg_commit(drv, 5);
return true;
}
@ -256,21 +303,16 @@ bool max2839_set_vga_gain(max2839_driver_t* const drv, const uint32_t gain_db) {
return false;
}
set_MAX2839_VGA(drv, 31-(gain_db >> 1) );
set_MAX2839_Rx1_VGAgain(drv, (63-gain_db));
max2839_reg_commit(drv, 5);
return true;
}
bool max2839_set_txvga_gain(max2839_driver_t* const drv, const uint32_t gain_db) {
uint16_t val=0;
if(gain_db <16){
val = 31-gain_db;
val |= (1 << 5); // bit6: 16db
} else{
val = 31-(gain_db-16);
}
val = 63-gain_db;
set_MAX2839_TXVGA_GAIN(drv, val);
set_MAX2839_TX_VGA_GAIN(drv, val);
max2839_reg_commit(drv, 29);
return true;
}

View File

@ -31,7 +31,9 @@ static inline void set_##n(max2839_driver_t* const _d, uint16_t v) { \
__MREG__(MAX2839_RESERVED_1, 0,9,10)
/* REG 1 */
__MREG__(MAX2839_LNAtune,1,1,2)
__MREG__(MAX2839_LNAband,1,1,2)
#define MAX2839_LNAband_2_4 0 // 2.3-2.5 GHz
#define MAX2839_LNAband_2_6 1 // 2.5-2.7 GHz
__MREG__(MAX2839_RESERVED_2,1,2,1)
__MREG__(MAX2839_MIMO_SELECT,1,3,1)
__MREG__(MAX2839_iqerr_trim,1,9,6)
@ -53,7 +55,7 @@ __MREG__(MAX2839_RESERVED_5,3,9,10)
__MREG__(MAX2839_RESERVED_6,4,1,2)
__MREG__(MAX2839_LPF_CUTOFF,4,3,2)
__MREG__(MAX2839_RESERVED_7,4,5,2)
__MREG__(MAX2839_LPF_RF_BAND,4,9,4)
__MREG__(MAX2839_FT,4,9,4)
#define MAX2839_FT_1_75M 0
#define MAX2839_FT_2_5M 1
#define MAX2839_FT_3_5M 2
@ -72,13 +74,17 @@ __MREG__(MAX2839_LPF_RF_BAND,4,9,4)
#define MAX2839_FT_28M 15
/* REG 5 */
__MREG__(MAX2839_LNA1gain_SPI,5,1,2)
#define MAX2839_LNAgain_MAX 0b000 // Pad in 8dB steps, bits reversed
#define MAX2839_LNAgain_M8 0b001
#define MAX2839_LNAgain_M16 0b010
#define MAX2839_LNAgain_M32 0b011
__MREG__(MAX2839_LNA1gain,5,1,2)
#define MAX2839_LNA1gain_MAX 0b000 // Pad in 8dB steps, bits reversed
#define MAX2839_LNA1gain_M8 0b001
#define MAX2839_LNA1gain_M16 0b010
#define MAX2839_LNA1gain_M32 0b011
__MREG__(MAX2839_Rx1_VGAgain,5,7,6)
__MREG__(MAX2839_LPFblock_MODE,5,9,2)
#define MAX2839_ModeCtrl_RxCalibration 0
#define MAX2839_ModeCtrl_RxLPF 1
#define MAX2839_ModeCtrl_TxLPF 2
#define MAX2839_ModeCtrl_LPFTrim 3
/* REG 6 */
__MREG__(MAX2839_LNA2gain_SPI,6,1,2)
@ -146,7 +152,7 @@ __MREG__(MAX2839_RESERVED_15,15,8,2)
__MREG__(MAX2839_RXHP_highpass_corner,15,9,1)
/* REG 16 */
__MREG__(MAX2839_chip_disable,16,0,1)
__MREG__(MAX2839_chip_enable,16,0,1)
__MREG__(MAX2839_RXTX_calibration_enable,16,1,1)
__MREG__(MAX2839_RESERVED_16,16,5,4)
__MREG__(MAX2839_PA_bias_DAC_SPI_enable,16,6,1)
@ -154,14 +160,18 @@ __MREG__(MAX2839_PA_bias_DAC_TX_mode_enable,16,7,1)
__MREG__(MAX2839_RESERVED_17,16,9,2)
/* REG 17 */
__MREG__(MAX2839_SYNTH_20bit_FDR_UH,17,9,10)
__MREG__(MAX2839_SYN_FRAC_LO,17,9,10)
/* REG 18 */
__MREG__(MAX2839_SYNTH_20bit_FDR_LH,18,9,10)
__MREG__(MAX2839_SYN_FRAC_HI,18,9,10)
/* REG 19 */
__MREG__(MAX2839_SYNTH_8bit_IDR,19,7,8)
__MREG__(MAX2839_LO_Gen_Band_Switch,19,9,2)
__MREG__(MAX2839_SYN_INT,19,7,8)
__MREG__(MAX2839_LOGEN_BSW,19,9,2)
#define MAX2839_LOGEN_BSW_2_3 0 // 2300 - <2400 MHz
#define MAX2839_LOGEN_BSW_2_4 1 // 2400 - <2500 MHz
#define MAX2839_LOGEN_BSW_2_5 2 // 2500 - <2600 MHz
#define MAX2839_LOGEN_BSW_2_6 3 // 2600 - <2700 MHz
/* REG 20 */
__MREG__(MAX2839_RESERVED_18,20,0,1)
@ -213,7 +223,7 @@ __MREG__(MAX2839_PADAC_Output_Current_Ctrl,28,5,6)
__MREG__(MAX2839_PADAC_TurnOn_Delay_Ctrl,28,9,4)
/* REG 29 */
__MREG__(MAX2839_TX_VGA_SPI_Gain_Ctrl_Addr27,29,5,6)
__MREG__(MAX2839_TX_VGA_GAIN,29,5,6)
__MREG__(MAX2839_RESERVED_29,29,9,4)
/* REG 30 */