h1r9: implement additional MAX2839 functions, change some mreg definition names, fix RF gain control math
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Reference in New Issue
Block a user