feat: add tx_params_t structure and related functions for transmission parameter management

This commit is contained in:
2025-08-14 18:20:19 +08:00
parent d80eeb7c3f
commit 42e6c4d213
2 changed files with 141 additions and 7 deletions

View File

@ -876,9 +876,26 @@ set_modulation_params(const uint8_t sf,
return spi::write_stream(RADIOLIB_SX126X_CMD_SET_MODULATION_PARAMS, data);
}
/**
* @brief Set the tx params object
*
* @param pwr
* @param ramp_time
* @note
*
* The output power is defined as power in dBm in a range of
*
- 17 (0xEF) to +14 (0x0E) dBm by step of 1 dB if low power PA is selected
- 9 (0xF7) to +22 (0x16) dBm by step of 1 dB if high power PA is selected
for LLCC68: The output power is defined as power in dBm in a range of - 9 (0xF7) to +22 (0x16)dBm by steps of 1dB.
Selection between high power PA and low power PA is done with the command SetPaConfig and the parameter deviceSel.
By default low power PA and +14 dBm are set.
*/
inline Result<Unit, error_t>
set_tx_params(const uint8_t pwr, const uint8_t ramp_time = RADIOLIB_SX126X_PA_RAMP_200U) {
const uint8_t data[] = {pwr, ramp_time};
set_tx_params(tx_params_t params) {
const uint8_t data[] = {static_cast<uint8_t>(params.power), static_cast<uint8_t>(params.ramp_time)};
return spi::write_stream(RADIOLIB_SX126X_CMD_SET_TX_PARAMS, data);
}
@ -909,17 +926,18 @@ set_packet_type(const PacketType packet_type) {
inline Result<Unit, error_t>
set_output_power(const int8_t power) {
if (not in_range(power, -9, 22)) {
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<uint8_t>{&ocp, 1});
APP_RADIO_RETURN_ERR(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(power);
res = set_tx_params(params);
APP_RADIO_RETURN_ERR(res);
// restore OCP configuration
return write_register(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, std::span<const uint8_t>{&ocp, 1});
@ -948,7 +966,7 @@ set_current_limit() {
return write_register(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, std::span<const uint8_t>{&raw, 1});
}
inline int chip_type_to_max_tx_power(const ChipType &chip) {
inline int8_t chip_type_to_max_tx_power(const ChipType &chip) {
switch (chip) {
case ChipType::LLCC68:
return 22;
@ -1367,7 +1385,16 @@ static constexpr auto begin = [](const lora_parameters_t &params) -> Result<Unit
packet_params.hdr_type);
APP_RADIO_RETURN_ERR_CTX(res, "set packet params");
res = set_output_power(chip_type_to_max_tx_power(chip));
int8_t power{};
if (params.tx_params.power == tx_params_t::TX_POWER_AUTO) {
power = chip_type_to_max_tx_power(chip);
} else {
power = params.tx_params.power;
}
tx_params_t tx_params{params.tx_params};
tx_params.power = power;
res = set_output_power(tx_params);
APP_RADIO_RETURN_ERR_CTX(res, "set output power");
res = fix_pa_clamping();

View File

@ -28,6 +28,26 @@ enum LoRaBandwidth : uint8_t {
BW_500_0 = 0x06,
};
// - RampTime Value RampTime (µs)
// - SET_RAMP_10U 0x00 10
// - SET_RAMP_20U 0x01 20
// - SET_RAMP_ 40U 0x02 40
// - SET_RAMP_80U 0x03 80
// - SET_RAMP_200U 0x04 200
// - SET_RAMP_800U 0x05 800
// - SET_RAMP_1700U 0x06 1700
// - SET_RAMP_3400U 0x07 3400
enum TxRampTime : uint8_t {
SET_RAMP_10U = 0x00,
SET_RAMP_20U = 0x01,
SET_RAMP_40U = 0x02,
SET_RAMP_80U = 0x03,
SET_RAMP_200U = 0x04,
SET_RAMP_800U = 0x05,
SET_RAMP_1700U = 0x06,
SET_RAMP_3400U = 0x07,
};
enum RegulatorMode : uint8_t {
REGULATOR_LDO = RADIOLIB_SX126X_REGULATOR_LDO,
REGULATOR_DC_DC = RADIOLIB_SX126X_REGULATOR_DC_DC,
@ -143,9 +163,62 @@ struct packet_params_t {
}
};
inline const char *to_str(llcc68::TxRampTime ramp_time) {
switch (ramp_time) {
case llcc68::SET_RAMP_10U:
return "10us";
case llcc68::SET_RAMP_20U:
return "20us";
case llcc68::SET_RAMP_40U:
return "40us";
case llcc68::SET_RAMP_80U:
return "80us";
case llcc68::SET_RAMP_200U:
return "200us";
case llcc68::SET_RAMP_800U:
return "800us";
case llcc68::SET_RAMP_1700U:
return "1700us";
case llcc68::SET_RAMP_3400U:
return "3400us";
default:
return "Unknown";
}
}
struct tx_params_t {
/**
* @brief magic number for automatic max TX power depending on
* chip type
*/
static constexpr auto TX_POWER_AUTO = 0x7f;
static constexpr auto MAX_POWER_HIGH_PA = 22;
static constexpr auto MAX_POWER_LOW_PA = 14;
int8_t power;
TxRampTime ramp_time;
static tx_params_t Default() {
return tx_params_t{
.power = MAX_POWER_HIGH_PA,
.ramp_time = SET_RAMP_200U,
};
}
[[nodiscard]]
std::string to_string() const {
if (power == TX_POWER_AUTO) {
return "tx_params: power=auto, ramp_time=" + std::string(to_str(ramp_time));
}
return std::format("tx_params: power={}, ramp_time={}",
power,
to_str(ramp_time));
}
};
struct lora_parameters_t {
modulation_params_t mod_params;
packet_params_t packet_params;
tx_params_t tx_params;
freq_t frequency;
uint8_t sync_word;
@ -153,6 +226,7 @@ struct lora_parameters_t {
return lora_parameters_t{
.mod_params = modulation_params_t::Default(),
.packet_params = packet_params_t::Default(),
.tx_params = tx_params_t::Default(),
.frequency = DEFAULT_FREQUENCY,
.sync_word = DEFAULT_SYNC_WORD,
};
@ -365,6 +439,7 @@ struct __attribute__((packed)) DeviceErrors {
// MSB
[[nodiscard]]
std::string to_string() const {
auto ss = std::stringstream();
ss << "DeviceErrors{";
@ -502,6 +577,38 @@ constexpr bool valid_sf(const uint8_t bw, const uint8_t sf) {
}
}
constexpr bool valid_tx_power(int8_t power) {
if (power == tx_params_t::TX_POWER_AUTO) {
return true;
}
if (power >= -9 && power <= 22) {
return true;
}
if (power >= -17 && power <= 14) {
return true;
}
return false;
}
constexpr bool valid_ramp_time(const llcc68::TxRampTime ramp_time) {
switch (ramp_time) {
case llcc68::SET_RAMP_10U:
case llcc68::SET_RAMP_20U:
case llcc68::SET_RAMP_40U:
case llcc68::SET_RAMP_80U:
case llcc68::SET_RAMP_200U:
case llcc68::SET_RAMP_800U:
case llcc68::SET_RAMP_1700U:
case llcc68::SET_RAMP_3400U:
return true;
default:
return false;
}
}
constexpr bool valid_freq(const freq_t freq) {
return in_range(freq, freq_t{150.0}, freq_t{960.0});
}