h1r9: MAX2839: emulate MAX2837 RX gain configuration

This commit is contained in:
Michael Ossmann
2022-10-03 06:08:59 -04:00
committed by Mike Walters
parent 5693f7b193
commit b15509c2d9

View File

@ -33,6 +33,9 @@
#include "max2839.h" #include "max2839.h"
#include "max2839_regs.def" // private register def macros #include "max2839_regs.def" // private register def macros
static uint8_t requested_lna_gain = 0;
static uint8_t requested_vga_gain = 0;
/* Default register values. */ /* Default register values. */
static const uint16_t max2839_regs_default[MAX2839_NUM_REGS] = { static const uint16_t max2839_regs_default[MAX2839_NUM_REGS] = {
0x000, /* 0 */ 0x000, /* 0 */
@ -300,39 +303,104 @@ uint32_t max2839_set_lpf_bandwidth(max2839_driver_t* const drv, const uint32_t b
return p->bandwidth_hz; return p->bandwidth_hz;
} }
bool max2839_set_lna_gain(max2839_driver_t* const drv, const uint32_t gain_db) { void max2839_configure_rx_gain(max2839_driver_t* const drv)
{
/*
* restrict requested LNA gain to valid MAX2837 settings:
* 0, 8, 16, 24, 32, or 40
*/
if (requested_lna_gain > 40) {
requested_lna_gain = 40;
}
requested_lna_gain &= 0x38;
/*
* restrict requested VGA gain to valid MAX2837 settings:
* even number, 0 through 62
*/
if (requested_vga_gain > 62) {
requested_vga_gain = 62;
}
requested_vga_gain &= 0x3e;
/*
* MAX2839 has lower full-scale RX output voltage than MAX2837, so we
* adjust the VGA (baseband) gain to compensate.
*/
uint8_t vga_gain = requested_vga_gain + 3;
uint8_t lna_gain = requested_lna_gain;
/*
* If that adjustment puts VGA gain out of range, use LNA gain to
* compensate. MAX2839 VGA gain can be any number from 0 through 63.
*/
if (vga_gain > 63) {
if (lna_gain <= 32) {
vga_gain -= 8;
lna_gain += 8;
} else {
vga_gain = 63;
}
}
/*
* MAX2839 lacks max-24 dB and max-40 dB LNA gain settings, so we use
* VGA gain to compensate.
*/
if (lna_gain == 0) {
lna_gain = 8;
vga_gain = (vga_gain >= 8) ? vga_gain - 8 : 0;
}
if (lna_gain == 16) {
if (vga_gain > 32) {
vga_gain -= 8;
lna_gain += 8;
} else {
vga_gain += 8;
lna_gain -= 8;
}
}
uint16_t val; uint16_t val;
switch(gain_db){ switch (lna_gain) {
case 40: case 40:
val = MAX2839_LNA2gain_MAX; val = MAX2839_LNA2gain_MAX;
break; break;
case 32: case 32:
val = MAX2839_LNA2gain_M8; val = MAX2839_LNA2gain_M8;
break; break;
case 24: case 24:
// FIXME correct missing settings with VGA adjustment? case 16:
case 16: val = MAX2839_LNA2gain_M16;
val = MAX2839_LNA2gain_M16; break;
break; case 8:
case 8: case 0:
case 0: default:
val = MAX2839_LNA2gain_M32; val = MAX2839_LNA2gain_M32;
break; break;
default:
return false;
} }
set_MAX2839_LNA2gain(drv, val); set_MAX2839_LNA2gain(drv, val);
max2839_reg_commit(drv, 6); set_MAX2839_Rx2_VGAgain(drv, (63 - vga_gain));
max2839_regs_commit(drv);
}
bool max2839_set_lna_gain(max2839_driver_t* const drv, const uint32_t gain_db)
{
if ((gain_db & 0x7) || gain_db > 40) {
return false;
}
requested_lna_gain = gain_db;
max2839_configure_rx_gain(drv);
return true; return true;
} }
bool max2839_set_vga_gain(max2839_driver_t* const drv, const uint32_t gain_db) { bool max2839_set_vga_gain(max2839_driver_t* const drv, const uint32_t gain_db)
if( (gain_db & 0x1) || gain_db > 62) {/* 0b11111*2 */ {
if ((gain_db & 0x1) || gain_db > 62) {
return false; return false;
} }
requested_vga_gain = gain_db;
set_MAX2839_Rx2_VGAgain(drv, (63-gain_db)); max2839_configure_rx_gain(drv);
max2839_reg_commit(drv, 6);
return true; return true;
} }