11#include "esphome/core/log.h"
12#include "esphome/core/application.h"
17static const char *
const TAG =
"home_io_control.sx1276";
22 this->
spi_->spi_enable();
23 this->
spi_->spi_write(reg & 0x7F);
24 uint8_t
const value = this->
spi_->spi_read();
25 this->
spi_->spi_disable();
30 this->
spi_->spi_enable();
31 this->
spi_->spi_write(reg | 0x80);
32 this->
spi_->spi_write(value);
33 this->
spi_->spi_disable();
41 uint32_t
const start = millis();
44 if (cur_mode == mode || (mode ==
MODE_RX && cur_mode == 0x04))
46 if (millis() - start > 50) {
47 ESP_LOGE(
TAG,
"Radio mode change timeout");
60 uint32_t
const start = millis();
62 if (millis() - start > 20) {
63 ESP_LOGE(
TAG,
"Image calibration timeout");
73 uint8_t raw_len,
const uint8_t *frame, uint8_t frame_len) {
87 uint64_t
const frf = ((uint64_t) freq_hz << 19) /
FXOSC;
111 ESP_LOGE(
TAG,
"SX1276 not found");
120 ESP_LOGI(
TAG,
"SX1276 initialized");
169 uint32_t
const br =
FXOSC / 38400;
174 auto fd = (uint32_t) ((19200.0F /
FXOSC) * (1 << 19));
180 uint8_t p = std::max(this->
tx_power_, (uint8_t) 2);
181 p = std::min(p, (uint8_t) 17);
209#ifdef IOHOME_FRAME_LOG
218 this->
spi_->spi_enable();
220 for (uint8_t i = 0; i < len; i++)
221 this->
spi_->spi_transfer(data[i]);
222 this->
spi_->spi_disable();
228 uint32_t
const start = millis();
230 if (millis() - start > 4000) {
231 ESP_LOGE(
TAG,
"TX timeout");
236 delayMicroseconds(100);
247 uint32_t
const start = millis();
255 if ((irq2 & 0x04) != 0)
257 if (millis() - start > timeout_ms)
281 bool saw_dio0 =
false;
288 if ((irq2 & 0x04) == 0) {
296#ifdef IOHOME_FRAME_LOG
298 log_frame(
"RX", packet.
data, packet.
len, this->current_freq_);
300 return packet.
len > 0;
311 if ((irq2 & 0x04) != 0) {
315#ifdef IOHOME_FRAME_LOG
317 log_frame(
"RX", packet.
data, packet.
len, this->current_freq_);
319 return packet.
len > 0;
322 if ((irq2 & 0x10) != 0) {
329 ESP_LOGCONFIG(
TAG,
" SX1276 Diagnostic:");
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_()
Hardware reset sequence common to all SX chips.
bool is_dio_fired() const
Set by the ISR when DIO fires.
RadioCaptureInfo last_capture_
void prepare_nonblocking_receive_(RadioRxPacket &packet)
Common preamble for non‑blocking receive: clear diagnostics, output packet, and DIO latch.
void prepare_blocking_receive_(RadioRxPacket &packet)
Common preamble for blocking receive: clear diagnostics and output packet.
void configure_radio_()
Perform full radio configuration (called during init).
int16_t read_rssi() override
Read instantaneous RSSI (dBm) while in RX mode (used for LBT).
bool wait_for_packet(RadioRxPacket &packet, uint32_t timeout_ms) override
Blocking wait for a packet with timeout.
uint8_t read_register_(uint8_t reg)
Read an SX1276 register over SPI.
InternalGPIOPin * dio4_pin_
void fill_capture_info_(bool blocking_wait, uint8_t irq1, uint8_t irq2, uint8_t rssi, const uint8_t *raw, uint8_t raw_len, const uint8_t *frame, uint8_t frame_len)
Populate last_capture_ from raw telemetry.
void set_mode_(uint8_t mode)
Set the operating mode (sleep/standby/tx/rx) and wait for mode completion.
RadioSX1276(SpiAccess *spi, InternalGPIOPin *rst_pin, InternalGPIOPin *dio0_pin, InternalGPIOPin *dio4_pin, uint8_t tx_power, uint8_t pa_pin)
void set_mode_standby() override
Switch radio into standby mode.
InternalGPIOPin * dio0_pin_
static void gpio_intr(RadioSX1276 *arg)
DIO0 ISR — sets dio_fired flag. Runs in interrupt context.
bool poll_until_payload_ready_(uint32_t timeout_ms, bool &saw_dio0, uint8_t &irq1, uint8_t &irq2)
Wait until FIFO payload is ready (polling for TX/RX readiness).
void dump_debug() override
Dump radio‑specific debug info to log.
void change_frequency(uint32_t freq_hz) override
Change RF frequency using fast hop (no standby needed).
bool init() override
Initialize the SX1276 radio (reset, calibrate, configure registers).
void write_register_(uint8_t reg, uint8_t value)
Write an SX1276 register over SPI.
void set_mode_rx() override
Switch radio into continuous receive mode.
uint8_t read_fifo_packet_(uint8_t *buf, uint8_t buf_size)
Read a packet from the RX FIFO into a buffer.
bool send_packet(const uint8_t *data, uint8_t len, const RadioTxConfig &tx_config) override
Transmit a frame with specified frequency and preamble.
bool check_for_packet(RadioRxPacket &packet) override
Non‑blocking check for a received packet (called from loop).
void run_image_cal_()
Run image calibration routine (required after reset).
Shared frame logging helpers for IO-Homecontrol.
static constexpr uint8_t REG_RX_CONFIG
Receiver configuration (AFC, AGC, trigger).
static constexpr uint8_t REG_IRQ_FLAGS1
IRQ flags: mode ready, preamble detect, etc.
static constexpr uint8_t REG_FRF_MSB
Carrier frequency MSB (freq = FRF * FXOSC / 2^19).
static constexpr uint8_t REG_PACKET_CONFIG2
Packet mode, IoHomeOn, PowerFrame.
static constexpr uint8_t REG_PA_CONFIG
Power amplifier config (pin select + power level).
static constexpr uint8_t REG_IRQ_FLAGS2
IRQ flags: FIFO full/empty, payload ready, CRC ok.
static constexpr uint8_t MODE_RX
static constexpr uint8_t REG_DIO_MAPPING1
DIO0-DIO3 pin mapping.
static constexpr uint8_t REG_FDEV_LSB
static constexpr uint8_t REG_DIO_MAPPING2
DIO4-DIO5 pin mapping.
static constexpr uint8_t REG_FIFO_THRESH
FIFO threshold for TX start condition.
static constexpr uint8_t REG_FIFO
FIFO read/write access.
static constexpr uint8_t REG_OP_MODE
Operating mode (sleep/standby/tx/rx).
static constexpr uint8_t REG_FDEV_MSB
Frequency deviation MSB.
static constexpr uint8_t MODE_TX
static constexpr uint8_t REG_PA_RAMP
PA ramp time and modulation shaping.
static constexpr uint8_t MODE_STDBY
static constexpr uint8_t REG_PAYLOAD_LENGTH
Max payload length.
static constexpr uint8_t REG_RX_BW
Receiver bandwidth.
static constexpr uint8_t REG_PACKET_CONFIG1
Packet format, CRC, encoding.
static constexpr uint8_t REG_BITRATE_MSB
Bit rate MSB = FXOSC / bitrate.
static constexpr uint8_t REG_SYNC_CONFIG
Sync word config (size, polarity, enable).
static constexpr uint8_t REG_AFC_FEI
AFC auto clear.
static constexpr uint8_t REG_PREAMBLE_LSB
static constexpr uint8_t REG_PLLHOP
PLL hop: fast frequency change without standby.
static constexpr uint8_t REG_LNA
Low noise amplifier gain and boost.
static constexpr uint32_t FREQ_CH2
Channel 2: 868.95 MHz (1W and 2W, TX channel).
static constexpr uint8_t MODE_MASK
static constexpr uint32_t FXOSC
SX1276 crystal oscillator frequency (32 MHz).
static constexpr uint8_t REG_IMAGE_CAL
Image calibration.
static constexpr uint8_t REG_RSSI_CONFIG
RSSI smoothing.
static constexpr uint8_t REG_OSC
Oscillator / clock output.
static constexpr uint8_t REG_VERSION
Chip version (should read 0x12 for SX1276).
static constexpr uint8_t REG_PREAMBLE_DETECT
Preamble detector config.
constexpr uint8_t RADIO_PACKET_BUFFER_SIZE
Scratch buffer size for raw radio packets and recovered frames.
static constexpr uint8_t REG_SYNC_VALUE1
Sync word byte 1 (registers 0x28-0x2F for bytes 1-8).
static constexpr uint8_t REG_RSSI_VALUE
Instant RSSI value in FSK mode.
static constexpr uint8_t REG_FRF_MID
static constexpr uint8_t REG_PREAMBLE_MSB
TX preamble length MSB.
static const char *const TAG
static constexpr uint8_t REG_BITRATE_LSB
static constexpr uint8_t REG_FRF_LSB
SX1276 radio driver for IO-Homecontrol.
Raw packet received from the radio.
uint8_t len
Length of packet in bytes.
uint32_t freq_hz
Frequency the packet was received on (Hz).
uint8_t data[RADIO_PACKET_BUFFER_SIZE]
Raw packet data buffer.
Configuration for transmitting a packet: carrier frequency and preamble length.
uint16_t preamble_len
Preamble length in symbol periods (bytes).
uint32_t freq_hz
Carrier frequency in Hz.