feat: introduce pa_setting_t structure for power amplifier configuration

This commit is contained in:
2025-08-15 16:30:23 +08:00
parent 42e6c4d213
commit 70a51cdb5c
2 changed files with 73 additions and 15 deletions

View File

@ -781,11 +781,9 @@ set_tx_infinite_preamble() {
* \param device_sel PA device selection; 0: SX1262, 1: SX1261 * \param device_sel PA device selection; 0: SX1262, 1: SX1261
*/ */
inline Result<Unit, error_t> inline Result<Unit, error_t>
set_pa_config(const uint8_t pa_duty_cycle, set_pa_config(pa_setting_t settings) {
const uint8_t hp_max = RADIOLIB_SX126X_PA_CONFIG_HP_MAX,
const uint8_t device_sel = RADIOLIB_SX126X_PA_CONFIG_SX1262) {
// paLut reserved and always 0x01 // 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); 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); return spi::write_stream(RADIOLIB_SX126X_CMD_SET_PACKET_TYPE, data);
} }
inline Result<Unit, error_t> inline Result<Unit, error_t>
set_output_power(tx_params_t params) { set_output_power(tx_params_t params) {
if (not in_range(params.power, -9, 22)) { if (not in_range(params.power, -9, 22)) {
return ue_t{error_t{error::RADIO_INVALID_OUTPUT_POWER}}; return ue_t{error_t{error::RADIO_INVALID_OUTPUT_POWER}};
} }
uint8_t ocp = 0; Result<Unit, error_t> res;
auto res = read_register(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, std::span<uint8_t>{&ocp, 1});
APP_RADIO_RETURN_ERR(res);
// TODO: optimal setting table: for now it was applied with +22dBm best setting // 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
res = set_pa_config(0x04); // is re-configured automatically each time the function SetPaConfig(...) is called.
APP_RADIO_RETURN_ERR(res); auto power = params.power;
res = set_tx_params(params); if (power == 22) {
APP_RADIO_RETURN_ERR(res); res = set_pa_config(pa_setting_t::Default22dBm());
// restore OCP configuration APP_RADIO_RETURN_ERR(res);
return write_register(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, std::span<const uint8_t>{&ocp, 1}); 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 {};
} }
/** /**

View File

@ -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) { inline const char *to_str(llcc68::TxRampTime ramp_time) {
switch (ramp_time) { switch (ramp_time) {
case llcc68::SET_RAMP_10U: case llcc68::SET_RAMP_10U: