22#include "esphome/core/log.h"
23#include "esphome/core/application.h"
30static const char *
const TAG =
"home_io_control.sx1262";
37 {SX1262_DEV_ERR_RC64K_CALIB,
"RC64K_CALIB_ERR"}, {SX1262_DEV_ERR_RC13M_CALIB,
"RC13M_CALIB_ERR"},
38 {SX1262_DEV_ERR_PLL_CALIB,
"PLL_CALIB_ERR"}, {SX1262_DEV_ERR_ADC_CALIB,
"ADC_CALIB_ERR"},
39 {SX1262_DEV_ERR_IMG_CALIB,
"IMG_CALIB_ERR"}, {SX1262_DEV_ERR_XOSC_START,
"XOSC_START_ERR"},
40 {SX1262_DEV_ERR_PLL_LOCK,
"PLL_LOCK_ERR"}, {SX1262_DEV_ERR_PA_RAMP,
"PA_RAMP_ERR"},
46constexpr uint32_t sx1262_tcxo_startup_ticks(uint32_t delay_us) {
return (delay_us * 64U + 999U) / 1000U; }
53constexpr int8_t SX1262_FEM_GAIN_GC1109_DB[22] = {
54 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 9, 8, 7,
56constexpr int8_t SX1262_FEM_GAIN_KCT8103L_DB[22] = {
57 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 11, 11, 10, 9, 8, 7,
69constexpr int8_t SX1262_FEM_GAIN_XY16P35_DB = 14;
71constexpr size_t SX1262_FEM_GAIN_TABLE_LEN = 22;
87constexpr FemRxGain SX1262_FEM_RX_GAIN_KCT8103L = {25,
"measured on a V4.3 against a V3, +/-4 dB"};
88constexpr FemRxGain SX1262_FEM_RX_GAIN_GC1109 = {15,
"quoted by Heltec, not measured here"};
89constexpr FemRxGain SX1262_FEM_RX_GAIN_XY16P35 = {0,
"not characterised: RSSI still includes the LNA gain"};
90constexpr FemRxGain SX1262_FEM_RX_GAIN_NONE = {0,
"no front end"};
94constexpr uint8_t SX1262_MAX_TX_POWER_DBM = 22;
101int8_t sx1262_fem_gain_db(
FemProfile profile, uint8_t tx_power_idx) {
104 return SX1262_FEM_GAIN_GC1109_DB[tx_power_idx];
106 return SX1262_FEM_GAIN_KCT8103L_DB[tx_power_idx];
108 return SX1262_FEM_GAIN_XY16P35_DB;
120const char *sx1262_fem_profile_name(
FemProfile profile) {
141const char *sx1262_fem_confidence_caveat(
FemProfile profile) {
145 return "+-5..7 dB, unmeasured";
147 return "vendor-measured but from five sparse points, not a real curve -- rougher than the other profiles' "
158int sx1262_fem_estimated_antenna_dbm(
FemProfile profile, uint8_t tx_power) {
160 tx_power < SX1262_FEM_GAIN_TABLE_LEN ? tx_power : static_cast<uint8_t>(SX1262_FEM_GAIN_TABLE_LEN - 1);
161 return static_cast<int>(tx_power) +
static_cast<int>(sx1262_fem_gain_db(profile, idx));
164constexpr const char *SX1262_FEM_COMPLIANCE_HINT =
165 "Verify against your local 868 MHz SRD/EIRP limit before relying on this for compliance";
172 return SX1262_FEM_RX_GAIN_GC1109;
174 return SX1262_FEM_RX_GAIN_KCT8103L;
176 return SX1262_FEM_RX_GAIN_XY16P35;
178 return SX1262_FEM_RX_GAIN_NONE;
180 return SX1262_FEM_RX_GAIN_NONE;
184 const uint8_t clamped = std::min<uint8_t>(tx_power, SX1262_MAX_TX_POWER_DBM);
185 return {clamped, sx1262_fem_estimated_antenna_dbm(profile, clamped)};
196 this->spi_->spi_enable();
197 this->spi_->spi_transfer(opcode);
198 for (uint8_t i = 0; i < len; i++)
199 this->spi_->spi_transfer(params[i]);
200 this->spi_->spi_disable();
205 this->spi_->spi_enable();
206 this->spi_->spi_transfer(opcode);
207 this->spi_->spi_transfer(0x00);
208 for (uint8_t i = 0; i < len; i++)
209 data[i] = this->spi_->spi_transfer(0x00);
210 this->spi_->spi_disable();
214 uint8_t irq_raw[2] = {0};
216 return (
static_cast<uint32_t
>(irq_raw[0]) << 8) |
static_cast<uint32_t
>(irq_raw[1]);
221 this->spi_->spi_enable();
222 this->spi_->spi_transfer(SX1262_WRITE_REGISTER);
223 this->spi_->spi_transfer((addr >> 8) & 0xFF);
224 this->spi_->spi_transfer(addr & 0xFF);
225 for (uint8_t i = 0; i < len; i++)
226 this->spi_->spi_transfer(data[i]);
227 this->spi_->spi_disable();
232 this->spi_->spi_enable();
233 this->spi_->spi_transfer(SX1262_READ_REGISTER);
234 this->spi_->spi_transfer((addr >> 8) & 0xFF);
235 this->spi_->spi_transfer(addr & 0xFF);
236 this->spi_->spi_transfer(0x00);
237 for (uint8_t i = 0; i < len; i++)
238 data[i] = this->spi_->spi_transfer(0x00);
239 this->spi_->spi_disable();
244 this->spi_->spi_enable();
245 this->spi_->spi_transfer(SX1262_WRITE_BUFFER);
246 this->spi_->spi_transfer(offset);
247 for (uint8_t i = 0; i < len; i++)
248 this->spi_->spi_transfer(data[i]);
249 this->spi_->spi_disable();
254 this->spi_->spi_enable();
255 this->spi_->spi_transfer(SX1262_READ_BUFFER);
256 this->spi_->spi_transfer(offset);
257 this->spi_->spi_transfer(0x00);
258 for (uint8_t i = 0; i < len; i++)
259 data[i] = this->spi_->spi_transfer(0x00);
260 this->spi_->spi_disable();
272 .preamble_detector = 0x04,
274 .packet_type = packet_type,
275 .payload_len = payload_len,
276 .crc_type = crc_type},
278 this->
write_opcode_(SX1262_SET_PACKET_PARAMS, params,
sizeof(params));
287 this->
set_packet_params_(8, SOFT_PHY_RX_PROBE_PACKET_LEN, SX1262_GFSK_PACKET_TYPE_KNOWN_LENGTH, SX1262_GFSK_CRC_OFF);
300 uint8_t mod_params[8] = {
305 static_cast<uint8_t
>(this->rx_bandwidth_),
310 this->
write_opcode_(SX1262_SET_MODULATION_PARAMS, mod_params,
sizeof(mod_params));
314 uint8_t clear_irq[2] = {
315 (uint8_t) ((irq_mask >> 8) & 0xFF),
316 (uint8_t) (irq_mask & 0xFF),
318 this->
write_opcode_(SX1262_CLEAR_IRQ_STATUS, clear_irq,
sizeof(clear_irq));
322 uint8_t errors_raw[2] = {0};
323 this->
read_opcode_(SX1262_GET_DEVICE_ERRORS, errors_raw,
sizeof(errors_raw));
324 return (uint16_t) (((uint16_t) errors_raw[0] << 8) | errors_raw[1]);
328 uint8_t clear_errors[2] = {0x00, 0x00};
329 this->
write_opcode_(SX1262_CLEAR_DEVICE_ERRORS, clear_errors,
sizeof(clear_errors));
333 uint8_t buf_base[2] = {SX1262_TX_BUFFER_BASE, SX1262_RX_BUFFER_BASE};
334 this->
write_opcode_(SX1262_SET_BUFFER_BASE_ADDRESS, buf_base,
sizeof(buf_base));
338 const uint8_t *raw, uint8_t raw_len,
const uint8_t *frame, uint8_t frame_len) {
339 uint8_t packet_status[3] = {0};
340 this->
read_opcode_(SX1262_GET_PACKET_STATUS, packet_status,
sizeof(packet_status));
343 raw_len, frame, frame_len);
359 uint8_t rx_status[2] = {0};
360 this->
read_opcode_(SX1262_GET_RX_BUFFER_STATUS, rx_status,
sizeof(rx_status));
361 reported_len = rx_status[0];
362 rx_offset = rx_status[1];
367 uint8_t tx_modulation = 0;
368 this->
read_register_(SX1262_REG_TX_MODULATION, &tx_modulation, 1);
369 tx_modulation |= SX1262_TX_MODULATION_GFSK_BIT;
375 uint8_t tx_timeout[3] = {0x03, 0xE8, 0x00};
376 this->
write_opcode_(SX1262_SET_TX, tx_timeout,
sizeof(tx_timeout));
388 this->dio1_pin_->setup();
396 if (this->vfem_pin_ !=
nullptr) {
397 this->vfem_pin_->setup();
398 this->vfem_pin_->digital_write(
true);
401 if (this->fem_en_pin_ !=
nullptr) {
402 this->fem_en_pin_->setup();
403 this->fem_en_pin_->digital_write(
true);
405 if (this->fem_pa_pin_ !=
nullptr) {
406 this->fem_pa_pin_->setup();
409 this->fem_pa_pin_->digital_write(
true);
430 "FEM profile %s active: tx_power %u is amplified by the front-end module to an "
431 "estimated ~%d dBm at the antenna port (%s). %s",
433 sx1262_fem_confidence_caveat(this->fem_profile_), SX1262_FEM_COMPLIANCE_HINT);
436 ESP_LOGI(
TAG,
"SX1262 initialized");
442 this->spi_->spi_enable();
443 uint8_t
const chip_status = this->spi_->spi_transfer(SX1262_GET_STATUS);
444 this->spi_->spi_transfer(0x00);
445 this->spi_->spi_disable();
447 uint8_t
const chip_mode = (chip_status >> 4) & 0x07;
448 uint8_t
const cmd_status = (chip_status >> 1) & 0x07;
449 const char *mode_str =
"?";
452 mode_str =
"STDBY_RC";
455 mode_str =
"STDBY_XOSC";
475 uint16_t
const irq = ((uint16_t) irq_raw[0] << 8) | irq_raw[1];
478 ESP_LOGCONFIG(
TAG,
" SX1262 Diagnostic:");
480 ESP_LOGCONFIG(
TAG,
" Chip status: 0x%02X (mode=%s, cmd=%u)", chip_status, mode_str, cmd_status);
481 ESP_LOGCONFIG(
TAG,
" BUSY=%d DIO1=%d", this->
busy_pin_->digital_read(), this->dio1_pin_->digital_read());
482 ESP_LOGCONFIG(
TAG,
" Sync word: %02X %02X %02X (expect 57 FD 99)", sync[0], sync[1], sync[2]);
483 ESP_LOGCONFIG(
TAG,
" IRQ status: 0x%04X", irq);
484 char errbuf[DEVICE_ERROR_STR_SIZE];
486 ESP_LOGCONFIG(
TAG,
" Device errors: 0x%04X (%s)", errors, errbuf);
487 if (this->tcxo_startup_attempts_ > 1) {
488 ESP_LOGCONFIG(
TAG,
" TCXO startup: %u attempts, %" PRIu32
" ms final delay",
489 static_cast<unsigned>(this->tcxo_startup_attempts_), this->tcxo_startup_delay_us_ / 1000);
500 ESP_LOGCONFIG(
TAG,
" Front-end module (FEM):");
501 ESP_LOGCONFIG(
TAG,
" Profile: %s", sx1262_fem_profile_name(this->fem_profile_));
502 LOG_PIN(
" VFEM Pin: ", this->vfem_pin_);
503 LOG_PIN(
" Enable Pin: ", this->fem_en_pin_);
504 LOG_PIN(
" PA/Mode Pin: ", this->fem_pa_pin_);
505 ESP_LOGCONFIG(
TAG,
" TX estimate: tx_power %u is amplified to ~%d dBm at the antenna port (%s)", estimate.
tx_power,
506 estimate.
antenna_dbm, sx1262_fem_confidence_caveat(this->fem_profile_));
507 ESP_LOGCONFIG(
TAG,
" %s", SX1262_FEM_COMPLIANCE_HINT);
509 ESP_LOGCONFIG(
TAG,
" RX gain removed from RSSI: %d dB (%s)",
static_cast<int>(rx_gain.
db), rx_gain.
basis);
516 static constexpr uint32_t TCXO_STARTUP_DELAYS_US[] = {5000, 10000, 50000};
519 static constexpr uint32_t TCXO_BUSY_MARGIN_MS = 25;
521 this->tcxo_startup_attempts_ = 0;
522 this->tcxo_startup_delay_us_ = 0;
531 uint16_t last_errors = 0;
532 for (
const uint32_t delay_us : TCXO_STARTUP_DELAYS_US) {
535 const uint32_t ticks = sx1262_tcxo_startup_ticks(delay_us);
536 uint8_t tcxo_params[4] = {this->tcxo_voltage_,
static_cast<uint8_t
>((ticks >> 16) & 0xFF),
537 static_cast<uint8_t
>((ticks >> 8) & 0xFF),
static_cast<uint8_t
>(ticks & 0xFF)};
538 this->
write_opcode_(SX1262_SET_DIO3_AS_TCXO_CTRL, tcxo_params,
sizeof(tcxo_params));
542 delay((delay_us / 1000) + 2);
549 uint8_t
const cal = 0x7F;
554 this->tcxo_startup_attempts_++;
555 this->tcxo_startup_delay_us_ = delay_us;
561 if ((last_errors & SX1262_DEV_ERR_XOSC_START) == 0)
572 if (this->tcxo_startup_attempts_ > 1) {
573 const uint32_t escalated = (this->tcxo_startup_delay_us_ / 1000) + TCXO_BUSY_MARGIN_MS;
574 this->
set_busy_timeout_ms_(saved_busy_timeout_ms > escalated ? saved_busy_timeout_ms : escalated);
584 if (this->tcxo_startup_attempts_ <= 1)
586 if ((last_errors & SX1262_DEV_ERR_XOSC_START) != 0) {
588 "SX1262 TCXO never started after %u attempts (XOSC_START_ERR persists) — check "
589 "tcxo_voltage for this board and the TCXO part itself",
590 static_cast<unsigned>(this->tcxo_startup_attempts_));
592 ESP_LOGW(
TAG,
"SX1262 TCXO started after %u attempts (%" PRIu32
" ms startup delay)",
593 static_cast<unsigned>(this->tcxo_startup_attempts_), this->tcxo_startup_delay_us_ / 1000);
599 uint8_t
const stdby_rc = 0x00;
609 uint8_t
const cal = 0x7F;
617 uint8_t
const stdby_xosc = 0x01;
621 uint8_t
const reg_mode = 0x01;
622 this->
write_opcode_(SX1262_SET_REGULATOR_MODE, ®_mode, 1);
625 uint8_t
const dio2_rf = 0x01;
626 this->
write_opcode_(SX1262_SET_DIO2_AS_RF_SWITCH_CTRL, &dio2_rf, 1);
629 uint8_t
const fallback_mode = SX1262_FALLBACK_STDBY_XOSC;
630 this->
write_opcode_(SX1262_SET_RX_TX_FALLBACK_MODE, &fallback_mode, 1);
633 uint8_t
const pkt_type = 0x00;
640 uint8_t cal_img[2] = {0xD7, 0xDB};
641 this->
write_opcode_(SX1262_CALIBRATE_IMAGE, cal_img,
sizeof(cal_img));
644 uint8_t
const rx_gain = 0x96;
657 uint8_t sync_word[8] = {0x57, 0xFD, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00};
658 this->
write_register_(SX1262_REG_SYNC_WORD, sync_word,
sizeof(sync_word));
663 uint8_t crc_init[2] = {0x1D, 0x0F};
665 uint8_t crc_poly[2] = {0x10, 0x21};
672 uint8_t pa_config[4] = {0x04, 0x07, 0x00, 0x01};
673 this->
write_opcode_(SX1262_SET_PA_CONFIG, pa_config,
sizeof(pa_config));
676 uint8_t tx_clamp = 0;
682 int8_t
const power = std::max((int8_t) -9, std::min((int8_t) SX1262_MAX_TX_POWER_DBM, (int8_t) this->tx_power_));
683 uint8_t tx_params[2] = {(uint8_t) power, 0x04};
684 this->
write_opcode_(SX1262_SET_TX_PARAMS, tx_params,
sizeof(tx_params));
694 uint8_t irq_params[8] = {
701 this->
write_opcode_(SX1262_SET_DIO_IRQ_PARAMS, irq_params,
sizeof(irq_params));
721 uint8_t rx_continuous[3] = {0xFF, 0xFF, 0xFF};
722 this->
write_opcode_(SX1262_SET_RX, rx_continuous,
sizeof(rx_continuous));
729 uint8_t
const stdby = 0x01;
735 uint8_t rx_continuous[3] = {0xFF, 0xFF, 0xFF};
736 this->
write_opcode_(SX1262_SET_RX, rx_continuous,
sizeof(rx_continuous));
758 auto freq_reg = (uint32_t) ((
double) freq_hz * (1 << 25) / 32e6);
759 uint8_t params[4] = {
760 (uint8_t) (freq_reg >> 24),
761 (uint8_t) (freq_reg >> 16),
762 (uint8_t) (freq_reg >> 8),
765 this->
write_opcode_(SX1262_SET_RF_FREQUENCY, params,
sizeof(params));
770 this->rx_bandwidth_ = bandwidth;
void populate_capture_base_(bool blocking_wait, uint32_t freq_hz, int16_t rssi_dbm, const uint8_t *raw, uint8_t raw_len, const uint8_t *frame, uint8_t frame_len)
Populate the common fields of RadioCaptureInfo from raw telemetry.
InternalGPIOPin * rst_pin_
void mark_dio_fired_from_isr()
void reset_hardware_()
Shared hardware reset sequence for chips with an active-low RST pin.
RadioCaptureInfo last_capture_
bool failed_
Latched by fail_; see is_failed.
void set_rx_packet_params() override
Configure RX-specific packet parameters (preamble detector length, fixed probe length).
RadioSX1262(SpiAccess *spi, InternalGPIOPin *rst_pin, InternalGPIOPin *dio1_pin, InternalGPIOPin *busy_pin, uint8_t tx_power, uint8_t tcxo_voltage, InternalGPIOPin *fem_en_pin=nullptr, InternalGPIOPin *vfem_pin=nullptr, InternalGPIOPin *fem_pa_pin=nullptr, FemProfile fem_profile=FemProfile::NONE)
void set_mode_rx() override
Switch to continuous receive mode.
void get_rx_buffer_status(uint8_t &reported_len, uint8_t &rx_offset) override
Read the chip-reported RX length and buffer offset (raw, before any clamping).
void write_opcode_(uint8_t opcode, const uint8_t *params, uint8_t len)
Write an opcode with optional parameter bytes.
void set_mode_standby() override
Switch to standby mode.
void clear_irq_status(uint32_t irq_mask) override
Clear IRQ status bits.
void write_modulation_params_()
Apply the runtime bandwidth setting to the SX1262 modulation parameters.
void write_buffer_(uint8_t offset, const uint8_t *data, uint8_t len)
Write into the SX1262 TX/RX buffer at a given offset.
void fem_set_rx_mode_()
Drive the FEM mode pin to its receive state (LNA), a no-op when no FEM profile is configured.
uint8_t read_rssi_raw_byte() override
Read the single raw RSSI byte (chip-specific opcode); formula is shared, see read_rssi.
uint32_t read_irq_status_raw() override
Read the raw IRQ status word from the radio.
void clear_device_errors_()
Clear device error flags.
void fem_set_tx_mode_()
Drive the FEM mode pin to its transmit state (full PA), a no-op when no FEM profile is configured.
void set_frequency_register(uint32_t freq_hz) override
Set RF frequency via the chip's own frequency register/opcode encoding, and update current_freq_.
void write_register_(uint16_t addr, const uint8_t *data, uint8_t len)
Write to a register (SX1262 uses opcodes for register access).
void configure_buffer_base() override
Hook run as part of reset_rx_state_, before re-entering RX.
void set_packet_params_(uint16_t preamble_len, uint8_t payload_len, uint8_t packet_type, uint8_t crc_type)
Configure packet parameters (preamble, payload length, CRC).
void dump_debug() override
Dump SX1262‑specific debug info.
void configure_radio_()
Full radio initialization (called from init()).
void start_tx() override
Issue the SetTx opcode with the fixed TX timeout — identical 3-byte payload on both chips,...
void apply_tx_modulation_workaround_()
Apply the Semtech TX modulation-quality erratum workaround (datasheet §15.1).
void configure_tcxo_()
Bring up the DIO3-controlled TCXO and calibrate, with a bounded XOSC-start retry.
static void gpio_intr(RadioSX1262 *arg)
DIO1 ISR — sets dio_fired flag. Runs in interrupt context.
void read_opcode_(uint8_t opcode, uint8_t *data, uint8_t len)
Read response from an opcode.
bool init() override
Initialize the radio hardware. Returns true on success.
void set_rx_bandwidth_(SX1262RxBandwidth bandwidth)
Apply the RX bandwidth selector and rewrite the modulation parameters.
void fill_capture_info(bool blocking_wait, uint32_t irq_status, uint8_t rx_offset, uint8_t reported_len, const uint8_t *raw, uint8_t raw_len, const uint8_t *frame, uint8_t frame_len) override
Populate the RadioCaptureInfo from chip-specific telemetry (RSSI opcode, packet-status byte,...
void read_buffer_(uint8_t offset, uint8_t *data, uint8_t len)
Read from the SX1262 RX buffer.
void read_register_(uint16_t addr, uint8_t *data, uint8_t len)
Read from a register.
void dump_front_end() override
Dump the FEM profile and its antenna-power estimate (nothing without a FEM).
bool fem_tx_active_level_() const
The level fem_pa_pin_ is driven to for the duration of a transmission, for the current fem_profile_.
uint16_t get_device_errors_()
Read device error flags (and clear them).
void wait_busy_()
Wait until busy_pin_ reads low, feeding the watchdog while polling.
void set_busy_timeout_ms_(uint32_t timeout_ms)
Set the wait_busy_ timeout, in milliseconds.
uint32_t get_busy_timeout_ms_() const
Current wait_busy_ timeout, in milliseconds.
void dump_init_device_errors_(const char *tag, DeviceErrorFormatter format) const
Log the init-time device errors under tag, or nothing when there were none.
int16_t raw_rssi_to_dbm_(uint8_t raw) const
Convert a chip's raw RSSI byte to an antenna-referred dBm reading.
static void build_gfsk_packet_params(const SoftPhyPacketParams &p, uint8_t out[GFSK_PACKET_PARAMS_LEN])
Fill the nine-byte GFSK SetPacketParams payload shared by both chips.
InternalGPIOPin * busy_pin_
BUSY line, read directly by both concrete drivers' own dump_debug() in addition to wait_busy_,...
static constexpr uint8_t GFSK_PACKET_PARAMS_LEN
Byte count of the GFSK SetPacketParams payload — identical on both software-PHY chips.
void record_init_device_errors_(const char *tag, const char *chip_label, uint16_t errors, DeviceErrorFormatter format)
Keep the device-error word read at the end of configure_radio_() and warn if it is non-zero.
SX1262RxBandwidth
Valid SX1262 RX bandwidth options (kHz register values).
static constexpr const char * TAG
FemProfile
Which RF front-end module (if any) sits between the SX1262 and the antenna.
@ XY16P35
LilyGO T-Beam 1W SX1262 (868 MHz).
@ KCT8103L
Heltec WiFi LoRa 32 V4.3 / V4 R8 – Kangxi KCT8103L. Mode pin active-HIGH during TX.
@ GC1109
Heltec WiFi LoRa 32 V4.2 – Geo-chip GC1109. Mode pin active-HIGH during TX.
@ NONE
No FEM, or a board with the FEM pins wired but no behaviour profile set – see the NONE-specific note ...
void sx1262_format_device_errors(uint16_t errors, char *buf, size_t buf_size)
Expand a GetDeviceErrors word into a human-readable NAME|NAME|... string.
const char * tcxo_voltage_label(uint8_t code)
Human-readable voltage for a tcxo_voltage code, for the config dump.
void format_device_error_bits(uint16_t errors, const DeviceErrorBit *bits, size_t bit_count, char *buf, size_t buf_size)
Expand a device-error word into a human-readable NAME|NAME|... string.
FemTxEstimate sx1262_fem_tx_estimate(FemProfile profile, uint8_t tx_power)
Estimate what a FEM profile radiates for a configured tx_power.
FemRxGain sx1262_fem_rx_gain(FemProfile profile)
The receive gain to remove from RSSI for a FEM profile.
constexpr uint8_t TCXO_VOLTAGE_NONE
Sentinel tcxo_voltage code (YAML none) for a board with a bare crystal and no TCXO.
static const uint8_t SX1262_SYNC_WORD_PARAM_24_BITS
static const char *const TAG
SX1262 radio driver for IO-Homecontrol.
One named bit of a chip's device-error word.
Receive-side gain of a FEM profile's LNA, in the SX1262's RSSI scale.
int8_t db
Gain (dB) the RSSI includes and the driver removes; 0 when unknown or absent.
const char * basis
Where the figure comes from and how far to trust it, for the config dump.
Antenna-port power estimate for a configured tx_power through a FEM profile's chain.
int antenna_dbm
Estimated antenna-port power in dBm — a rough bound, not a calibrated figure.
uint8_t tx_power
The tx_power actually programmed: the configured value clamped to SetTxParams' range.
uint16_t irq_status
Raw IRQ status register value.
uint8_t packet_status
Packet status byte (chip-specific).
bool crc_error
True if a CRC error was detected.
uint8_t reported_len
Length reported by the radio chip.
bool rx_done
True if RxDone IRQ fired.
uint8_t rx_offset
RX buffer offset where the frame starts (0 for chips without offset reporting).