feat: add TX continuous wave mode and update regulator mode handling

This commit is contained in:
2025-08-07 12:01:12 +08:00
parent 249c125447
commit c4a61d2708
2 changed files with 55 additions and 28 deletions

View File

@ -99,7 +99,7 @@ constexpr bool USE_REGULATOR_LDO = false;
TCXO (Temperature Compensated Crystal Oscillator) will be disabled if this is set to true TCXO (Temperature Compensated Crystal Oscillator) will be disabled if this is set to true
*/ */
constexpr bool USE_XTAL = true; constexpr bool USE_TXCO = false;
constexpr llcc68::TcxoVoltage DEFAULT_TCXO_VOLTAGE = TcxoVoltage::V_1_6; constexpr llcc68::TcxoVoltage DEFAULT_TCXO_VOLTAGE = TcxoVoltage::V_1_6;
using error_t = spi::error_t; using error_t = spi::error_t;
@ -117,9 +117,7 @@ struct transmit_state_t {
/** /**
* @brief private namespace; Don't use anything in this namespace outside of this file * @brief private namespace; Don't use anything in this namespace outside of this file
*/ */
namespace details { namespace details {}
inline uint32_t __tcxo_delay__;
}
constexpr auto delay_ms = app::utils::delay_ms; constexpr auto delay_ms = app::utils::delay_ms;
@ -235,7 +233,7 @@ set_buffer_base_address(const uint8_t txBaseAddress = DEFAULT_TX_BUFFER_ADDRESS,
} }
inline Result<Unit, error_t> inline Result<Unit, error_t>
set_regulator_mode(const uint8_t mode) { set_regulator_mode(const enum RegulatorMode mode) {
const uint8_t data[] = {mode}; const uint8_t data[] = {mode};
return spi::write_stream(RADIOLIB_SX126X_CMD_SET_REGULATOR_MODE, data); return spi::write_stream(RADIOLIB_SX126X_CMD_SET_REGULATOR_MODE, data);
} }
@ -703,6 +701,23 @@ set_cad() {
return spi::write_stream(RADIOLIB_SX126X_CMD_SET_CAD, data); return spi::write_stream(RADIOLIB_SX126X_CMD_SET_CAD, data);
} }
/**
* \brief Set the TX continuous wave mode
* \note CW
*/
inline Result<Unit, error_t>
set_tx_continuous_wave() {
const uint8_t data[] = {spi::SPI_NOP_COMMAND};
return spi::write_stream(RADIOLIB_SX126X_CMD_SET_TX_CONTINUOUS_WAVE, data);
}
inline Result<Unit, error_t>
set_tx_infinite_preamble() {
const uint8_t data[] = {spi::SPI_NOP_COMMAND};
return spi::write_stream(RADIOLIB_SX126X_CMD_SET_TX_INFINITE_PREAMBLE, data);
}
/** /**
* \brief Set the PA configuration * \brief Set the PA configuration
* \param pa_duty_cycle paDutyCycle controls the duty cycle (conduction angle) of both PAs (SX1261 and SX1262). The maximum output power, the * \param pa_duty_cycle paDutyCycle controls the duty cycle (conduction angle) of both PAs (SX1261 and SX1262). The maximum output power, the
@ -871,16 +886,6 @@ set_output_power(const int8_t power) {
return write_register(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, std::span<const uint8_t>{&ocp, 1}); return write_register(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, std::span<const uint8_t>{&ocp, 1});
} }
inline Result<Unit, error_t>
set_regulator_ldo() {
return set_regulator_mode(RADIOLIB_SX126X_REGULATOR_LDO);
}
inline Result<Unit, error_t>
set_regulator_dc_dc() {
return set_regulator_mode(RADIOLIB_SX126X_REGULATOR_DC_DC);
}
/** /**
* \brief checks if BUSY pin is low * \brief checks if BUSY pin is low
* \return true if BUSY pin is low, false otherwise * \return true if BUSY pin is low, false otherwise
@ -1250,12 +1255,34 @@ static constexpr auto begin = [](const lora_parameters_t &params) -> Result<Unit
return ue_t{error_t{error::RADIO_CHIP_NOT_FOUND}}; return ue_t{error_t{error::RADIO_CHIP_NOT_FOUND}};
} }
// FIXME /**
// according to https://github.com/nopnop2002/esp-idf-sx126x * FIXME
// we should set TCXO voltage *
if constexpr (not USE_XTAL) { * The hardware of the SX126x chips can be designed to use either an
const auto voltage_ = set_TCXO(DEFAULT_TCXO_VOLTAGE); * internal LDO or an internal DCDC converter. The DCDC converter provides
details::__tcxo_delay__ = *voltage_; * better current savings and will be used in most modules. If there are
* problems to get the SX126x to work, check which HW configuration is used
* and set USE_LDO accordingly.
* If USE_LDO is not set in the hwConfig, DCDC is used as default.
*
* - RADIO_TXEN and RADIO_RXEN are used on eByte E22-900M22S module to
* switch the antenna between RX and TX
* - DIO2 as antenna switch is used in the example Semtech design as default
* and might be used by many modules
* - DIO3 as antenna switch is used by e.g. Insight SIP ISP4520 module which
* integrates a nRF52832 and a SX126x chip
* - Some modules use DIO3 to control the power supply of the TXCO.
* - Some modules use DIO2 to switch the antenna between RX and TX and a
* separate GPIO to power the antenna switch on or off. Switching the
* antenna switch off can reduce the power consumption. The GPIO used to
* control the antenna power is defined as RADIO_RXEN. LOW == power off,
* HIGH == power on.
*
* @sa https://github.com/beegee-tokyo/SX126x-Arduino?tab=readme-ov-file#explanation-for-ldo-and-dcdc-selection
*/
if constexpr (USE_TXCO) {
const auto res = set_TCXO(DEFAULT_TCXO_VOLTAGE);
APP_RADIO_RETURN_ERR_CTX(res, "set TCXO"); APP_RADIO_RETURN_ERR_CTX(res, "set TCXO");
} }
const auto &mod_params = params.mod_params; const auto &mod_params = params.mod_params;
@ -1274,13 +1301,8 @@ static constexpr auto begin = [](const lora_parameters_t &params) -> Result<Unit
res = set_lora_sync_word(params.sync_word); res = set_lora_sync_word(params.sync_word);
APP_RADIO_RETURN_ERR_CTX(res, "sync word"); APP_RADIO_RETURN_ERR_CTX(res, "sync word");
if constexpr (USE_REGULATOR_LDO) { res = set_regulator_mode(USE_REGULATOR_LDO ? RegulatorMode::REGULATOR_LDO : RegulatorMode::REGULATOR_DC_DC);
res = set_regulator_ldo(); APP_RADIO_RETURN_ERR_CTX(res, "set regulator mode");
APP_RADIO_RETURN_ERR_CTX(res, "regulator LDO");
} else {
res = set_regulator_dc_dc();
APP_RADIO_RETURN_ERR_CTX(res, "regulator DC-DC");
}
res = set_current_limit<60.0f>(); res = set_current_limit<60.0f>();
APP_RADIO_RETURN_ERR_CTX(res, "current limit"); APP_RADIO_RETURN_ERR_CTX(res, "current limit");

View File

@ -27,6 +27,11 @@ enum LoRaBandwidth : uint8_t {
BW_500_0 = 0x06, BW_500_0 = 0x06,
}; };
enum RegulatorMode : uint8_t {
REGULATOR_LDO = RADIOLIB_SX126X_REGULATOR_LDO,
REGULATOR_DC_DC = RADIOLIB_SX126X_REGULATOR_DC_DC,
};
inline const char *to_str(LoRaBandwidth bw) { inline const char *to_str(LoRaBandwidth bw) {
switch (bw) { switch (bw) {
case LoRaBandwidth::BW_7_8: case LoRaBandwidth::BW_7_8: