From 70a51cdb5cbf280cd03f1a4eaf849e2cc543cc99 Mon Sep 17 00:00:00 2001 From: crosstyan Date: Fri, 15 Aug 2025 16:30:23 +0800 Subject: [PATCH] feat: introduce pa_setting_t structure for power amplifier configuration --- inc/llcc68.hpp | 56 ++++++++++++++++++++++++++++---------- inc/llcc68_definitions.hpp | 32 ++++++++++++++++++++++ 2 files changed, 73 insertions(+), 15 deletions(-) diff --git a/inc/llcc68.hpp b/inc/llcc68.hpp index d57729c..8d9f31e 100644 --- a/inc/llcc68.hpp +++ b/inc/llcc68.hpp @@ -781,11 +781,9 @@ set_tx_infinite_preamble() { * \param device_sel PA device selection; 0: SX1262, 1: SX1261 */ inline Result -set_pa_config(const uint8_t pa_duty_cycle, - const uint8_t hp_max = RADIOLIB_SX126X_PA_CONFIG_HP_MAX, - const uint8_t device_sel = RADIOLIB_SX126X_PA_CONFIG_SX1262) { +set_pa_config(pa_setting_t settings) { // paLut reserved and always 0x01 - const uint8_t data[] = {pa_duty_cycle, hp_max, device_sel, RADIOLIB_SX126X_PA_CONFIG_PA_LUT}; + const uint8_t data[] = {settings.pa_duty_cycle, settings.hp_max, settings.device_sel, RADIOLIB_SX126X_PA_CONFIG_PA_LUT}; return spi::write_stream(RADIOLIB_SX126X_CMD_SET_PA_CONFIG, data); } @@ -924,23 +922,51 @@ set_packet_type(const PacketType packet_type) { return spi::write_stream(RADIOLIB_SX126X_CMD_SET_PACKET_TYPE, data); } - inline Result set_output_power(tx_params_t params) { if (not in_range(params.power, -9, 22)) { return ue_t{error_t{error::RADIO_INVALID_OUTPUT_POWER}}; } - uint8_t ocp = 0; - auto res = read_register(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, std::span{&ocp, 1}); - APP_RADIO_RETURN_ERR(res); + Result res; - // TODO: optimal setting table: for now it was applied with +22dBm best setting - res = set_pa_config(0x04); - APP_RADIO_RETURN_ERR(res); - res = set_tx_params(params); - APP_RADIO_RETURN_ERR(res); - // restore OCP configuration - return write_register(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, std::span{&ocp, 1}); + // The OCP value is given on 6 bits, therefore the max OCP is 63 * 2.5mA = 157.5mA. It is configurable in steps of 2.5mA and the default value + // is re-configured automatically each time the function SetPaConfig(...) is called. + auto power = params.power; + if (power == 22) { + res = set_pa_config(pa_setting_t::Default22dBm()); + APP_RADIO_RETURN_ERR(res); + params.power = 22; + res = set_tx_params(params); + APP_RADIO_RETURN_ERR(res); + } else if (power == 20) { + // NOTE: it's optimal to set tx params to +22dBm + // and adjust the actual power by changing the duty cycle + res = set_pa_config(pa_setting_t::Default20dBm()); + APP_RADIO_RETURN_ERR(res); + params.power = 22; + res = set_tx_params(params); + APP_RADIO_RETURN_ERR(res); + } else if (power == 17) { + res = set_pa_config(pa_setting_t::Default17dBm()); + APP_RADIO_RETURN_ERR(res); + params.power = 22; + res = set_tx_params(params); + APP_RADIO_RETURN_ERR(res); + } else if (power == 14) { + res = set_pa_config(pa_setting_t::Default14dBm()); + APP_RADIO_RETURN_ERR(res); + params.power = 22; + res = set_tx_params(params); + APP_RADIO_RETURN_ERR(res); + } else { + // other power levels + // adjust tx params to achieve expected output power + res = set_pa_config(pa_setting_t::Default()); + APP_RADIO_RETURN_ERR(res); + res = set_tx_params(params); + APP_RADIO_RETURN_ERR(res); + } + return {}; } /** diff --git a/inc/llcc68_definitions.hpp b/inc/llcc68_definitions.hpp index eff9c1e..24d5d29 100644 --- a/inc/llcc68_definitions.hpp +++ b/inc/llcc68_definitions.hpp @@ -163,6 +163,38 @@ struct packet_params_t { } }; +struct pa_setting_t { + uint8_t pa_duty_cycle; + uint8_t hp_max; + uint8_t device_sel; + + static constexpr pa_setting_t Default22dBm() { + return {0x04, 0x07, 0x00}; + } + /** + * @note SetTxParams should be set to +22dBm + */ + static constexpr pa_setting_t Default20dBm() { + return {0x03, 0x05, 0x00}; + } + /** + * @note SetTxParams should be set to +22dBm + */ + static constexpr pa_setting_t Default17dBm() { + return {0x02, 0x03, 0x00}; + } + /** + * @note SetTxParams should be set to +14dBm + */ + static constexpr pa_setting_t Default14dBm() { + return {0x02, 0x02, 0x00}; + } + + static constexpr pa_setting_t Default() { + return Default22dBm(); + } +}; + inline const char *to_str(llcc68::TxRampTime ramp_time) { switch (ramp_time) { case llcc68::SET_RAMP_10U: