From e78e8d7c3f90c418ca6855bb4c963e7e5e20ca24 Mon Sep 17 00:00:00 2001 From: "Kenneth J. Miller" Date: Fri, 14 Apr 2023 01:47:06 +0200 Subject: [PATCH] drivers: lora: sx126x: Support fine-grained STM32WL PA config Add STM32WL-specific sx126x_set_tx_params function based on the STM32CubeWL modifications to LoRaMac-node. Add the "power-amplifier-output" DT property to "st,stm32wl-subghz-radio" for selecting between the RFO_LP and RFO_HP output configurations provided by the above mentioned function. Add the "rfo-lp-max-power" and "rfo-hp-max-power" DT properties for defining the maximum design power of the respective outputs' matching networks. closes #48511 Signed-off-by: Kenneth J. Miller --- drivers/lora/sx126x.c | 2 +- drivers/lora/sx126x_common.h | 3 + drivers/lora/sx126x_standalone.c | 5 ++ drivers/lora/sx126x_stm32wl.c | 70 +++++++++++++++++++ .../lora/st,stm32wl-subghz-radio.yaml | 42 +++++++++++ 5 files changed, 121 insertions(+), 1 deletion(-) diff --git a/drivers/lora/sx126x.c b/drivers/lora/sx126x.c index 227acb5435a..aeb9efe8981 100644 --- a/drivers/lora/sx126x.c +++ b/drivers/lora/sx126x.c @@ -359,7 +359,7 @@ void SX126xReset(void) void SX126xSetRfTxPower(int8_t power) { LOG_DBG("power: %" PRIi8, power); - SX126xSetTxParams(power, RADIO_RAMP_40_US); + sx126x_set_tx_params(power, RADIO_RAMP_40_US); } void SX126xWaitOnBusy(void) diff --git a/drivers/lora/sx126x_common.h b/drivers/lora/sx126x_common.h index 54759365636..81ac661859c 100644 --- a/drivers/lora/sx126x_common.h +++ b/drivers/lora/sx126x_common.h @@ -15,6 +15,7 @@ #include #include +#include #if DT_HAS_COMPAT_STATUS_OKAY(semtech_sx1261) #define DT_DRV_COMPAT semtech_sx1261 @@ -64,6 +65,8 @@ void sx126x_dio1_irq_enable(struct sx126x_data *dev_data); void sx126x_dio1_irq_disable(struct sx126x_data *dev_data); +void sx126x_set_tx_params(int8_t power, RadioRampTimes_t ramp_time); + int sx126x_variant_init(const struct device *dev); #endif /* ZEPHYR_DRIVERS_SX126X_COMMON_H_ */ diff --git a/drivers/lora/sx126x_standalone.c b/drivers/lora/sx126x_standalone.c index 2a2c3d5ea12..c9b16965bc7 100644 --- a/drivers/lora/sx126x_standalone.c +++ b/drivers/lora/sx126x_standalone.c @@ -61,6 +61,11 @@ static void sx126x_dio1_irq_callback(const struct device *dev, } } +void sx126x_set_tx_params(int8_t power, RadioRampTimes_t ramp_time) +{ + SX126xSetTxParams(power, ramp_time); +} + int sx126x_variant_init(const struct device *dev) { struct sx126x_data *dev_data = dev->data; diff --git a/drivers/lora/sx126x_stm32wl.c b/drivers/lora/sx126x_stm32wl.c index 76b78efc92b..c6a484ab34f 100644 --- a/drivers/lora/sx126x_stm32wl.c +++ b/drivers/lora/sx126x_stm32wl.c @@ -16,6 +16,11 @@ #include LOG_MODULE_DECLARE(sx126x, CONFIG_LORA_LOG_LEVEL); +static const enum { + RFO_LP, + RFO_HP, +} pa_output = DT_INST_STRING_UPPER_TOKEN(0, power_amplifier_output); + void sx126x_reset(struct sx126x_data *dev_data) { LL_RCC_RF_EnableReset(); @@ -45,6 +50,71 @@ void sx126x_dio1_irq_disable(struct sx126x_data *dev_data) irq_disable(DT_INST_IRQN(0)); } +void sx126x_set_tx_params(int8_t power, RadioRampTimes_t ramp_time) +{ + uint8_t buf[2]; + + if (pa_output == RFO_LP) { + const int8_t max_power = DT_INST_PROP(0, rfo_lp_max_power); + + if (power > max_power) { + power = max_power; + } + if (max_power == 15) { + SX126xSetPaConfig(0x07, 0x00, 0x01, 0x01); + power = 14 - (max_power - power); + } else if (max_power == 10) { + SX126xSetPaConfig(0x01, 0x00, 0x01, 0x01); + power = 13 - (max_power - power); + } else { /* default +14 dBm */ + SX126xSetPaConfig(0x04, 0x00, 0x01, 0x01); + power = 14 - (max_power - power); + } + if (power < -17) { + power = -17; + } + + /* PA overcurrent protection limit 60 mA */ + SX126xWriteRegister(REG_OCP, 0x18); + } else { /* RFO_HP */ + /* Better Resistance of the RFO High Power Tx to Antenna + * Mismatch, see STM32WL Erratasheet + */ + SX126xWriteRegister(REG_TX_CLAMP_CFG, + SX126xReadRegister(REG_TX_CLAMP_CFG) + | (0x0F << 1)); + + const int8_t max_power = DT_INST_PROP(0, rfo_hp_max_power); + + if (power > max_power) { + power = max_power; + } + if (max_power == 20) { + SX126xSetPaConfig(0x03, 0x05, 0x00, 0x01); + power = 22 - (max_power - power); + } else if (max_power == 17) { + SX126xSetPaConfig(0x02, 0x03, 0x00, 0x01); + power = 22 - (max_power - power); + } else if (max_power == 14) { + SX126xSetPaConfig(0x02, 0x02, 0x00, 0x01); + power = 14 - (max_power - power); + } else { /* default +22 dBm */ + SX126xSetPaConfig(0x04, 0x07, 0x00, 0x01); + power = 22 - (max_power - power); + } + if (power < -9) { + power = -9; + } + + /* PA overcurrent protection limit 140 mA */ + SX126xWriteRegister(REG_OCP, 0x38); + } + + buf[0] = power; + buf[1] = (uint8_t)ramp_time; + SX126xWriteCommand(RADIO_SET_TXPARAMS, buf, 2); +} + static void radio_isr(const struct device *dev) { struct sx126x_data *dev_data = dev->data; diff --git a/dts/bindings/lora/st,stm32wl-subghz-radio.yaml b/dts/bindings/lora/st,stm32wl-subghz-radio.yaml index fb2a54486b3..4066c1bcb2c 100644 --- a/dts/bindings/lora/st,stm32wl-subghz-radio.yaml +++ b/dts/bindings/lora/st,stm32wl-subghz-radio.yaml @@ -12,3 +12,45 @@ properties: required: true description: | Position of the "Radio IRQ, Busy" interrupt line. + + power-amplifier-output: + type: string + required: true + description: | + Selects between the low- and high-power power amplifier output pin. + enum: + - "rfo-lp" + - "rfo-hp" + + rfo-lp-max-power: + type: int + default: 14 + description: | + Maximum design power for the board's RFO_LP output matching network. + + The default setting of +14 dBm is a prevalent board configuration; + however, for optimal performance, it is advisable to align the value with + the board's RF design. + + See ST application note AN5457, chapter 5.1.2 for more information. + enum: + - 10 + - 14 + - 15 + + rfo-hp-max-power: + type: int + default: 22 + description: | + Maximum design power for the board's RFO_HP output matching network. + + The default setting of +22 dBm is a prevalent board configuration; + however, for optimal performance, it is advisable to align the value with + the board's RF design. + + See ST application note AN5457, chapter 5.1.2 for more information. + enum: + - 14 + - 17 + - 20 + - 22