drivers: lora: sx1276: fix RFO TX power configuration

The PA_CONFIG register is currently not setup correctly for the RFO
path. The biggest problem is that the output power is incorrectly set
1dBm higher than requested. Additionally, the lower power levels are
not configured properly since the max power field in PA_CONFIG is
always configured for an output power between 0 and 15dBm.

To support lower than 0dBm, adjust the max power field in the
PA_CONFIG register to shift the output power range to -4--11 dBm when
the requested power is 0 or lower.

Signed-off-by: Andreas Sandberg <andreas@sandberg.pp.se>
[Marcin: rebase on master]
Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com>
This commit is contained in:
Andreas Sandberg 2020-04-17 10:51:36 +01:00 committed by Carles Cufí
commit 8d332adf1a

View file

@ -27,6 +27,8 @@ LOG_MODULE_REGISTER(sx1276);
#define SX1276_REG_PA_DAC 0x4d
#define SX1276_REG_VERSION 0x42
#define SX1276_PA_CONFIG_MAX_POWER_SHIFT 4
extern DioIrqHandler *DioIrq[];
struct sx1276_dio {
@ -58,6 +60,17 @@ static struct sx1276_data {
struct k_work dio_work[SX1276_MAX_DIO];
} dev_data;
static int8_t clamp_int8(int8_t x, int8_t min, int8_t max)
{
if (x < min) {
return min;
} else if (x > max) {
return max;
} else {
return x;
}
}
bool SX1276CheckRfFrequency(uint32_t frequency)
{
/* TODO */
@ -230,47 +243,37 @@ void SX1276SetRfTxPower(int8_t power)
return;
}
pa_config = (pa_config & RF_PACONFIG_MAX_POWER_MASK) | 0x70;
pa_config &= RF_PACONFIG_MAX_POWER_MASK;
pa_config &= RF_PACONFIG_OUTPUTPOWER_MASK;
pa_config &= RF_PACONFIG_PASELECT_MASK;
pa_dac &= RF_PADAC_20DBM_MASK;
#if defined CONFIG_PA_BOOST_PIN
power = clamp_int8(power, 2, 20);
pa_config |= RF_PACONFIG_PASELECT_PABOOST;
if (power > 17) {
pa_dac = (pa_dac & RF_PADAC_20DBM_MASK) | RF_PADAC_20DBM_ON;
pa_dac |= RF_PADAC_20DBM_ON;
pa_config |= (power - 5) & 0x0F;
} else {
pa_dac = (pa_dac & RF_PADAC_20DBM_MASK) | RF_PADAC_20DBM_OFF;
}
if ((pa_dac & RF_PADAC_20DBM_ON) == RF_PADAC_20DBM_ON) {
if (power < 5) {
power = 5;
} else if (power > 20) {
power = 20;
}
pa_config = (pa_config & RF_PACONFIG_OUTPUTPOWER_MASK) |
((power - 5) & 0x0F);
} else {
if (power < 2) {
power = 2;
} else if (power > 17) {
power = 17;
}
pa_config = (pa_config & RF_PACONFIG_OUTPUTPOWER_MASK) |
((power - 2) & 0x0F);
pa_dac |= RF_PADAC_20DBM_OFF;
pa_config |= (power - 2) & 0x0F;
}
#elif CONFIG_PA_RFO_PIN
if (power < -1) {
power = -1;
} else if (power > 14) {
power = 14;
}
power = clamp_int8(power, -4, 15);
pa_config = (pa_config & RF_PACONFIG_OUTPUTPOWER_MASK) |
((power + 1) & 0x0F);
pa_dac |= RF_PADAC_20DBM_OFF;
if (power > 0) {
/* Set the power range to 0 -- 10.8+0.6*7 dBm. */
pa_config |= 7 << SX1276_PA_CONFIG_MAX_POWER_SHIFT;
pa_config |= (power & 0x0F);
} else {
/* Set the power range to -4.2 -- 10.8+0.6*0 dBm */
pa_config |= ((power + 4) & 0x0F);
}
#endif
ret = sx1276_write(SX1276_REG_PA_CONFIG, &pa_config, 1);
if (ret < 0) {
LOG_ERR("Unable to write PA config");