81 "a budget below the minimum window makes try_early_completion_() decline every "
82 "idle-path call, silently turning issue #81's fix into a no-op");
105 "the hop holdoff must outlast the fixed-length RX_DONE it exists to wait for — a "
106 "shorter bound lets the hop fire while the frame it is protecting is still on air, "
107 "silently turning issue #81's gate back into the bug");
125 SoftPhyDriverBase(InternalGPIOPin *rst_pin, InternalGPIOPin *busy_pin, uint32_t busy_timeout_ms,
126 uint16_t default_response_preamble, uint16_t default_post_tx_settle_us)
129 response_preamble_(default_response_preamble),
130 post_tx_settle_us_(default_post_tx_settle_us),
131 busy_timeout_ms_(busy_timeout_ms) {}
303 virtual void fill_capture_info(
bool blocking_wait, uint32_t irq_status, uint8_t rx_offset, uint8_t reported_len,
304 const uint8_t *raw, uint8_t raw_len,
const uint8_t *frame, uint8_t frame_len) = 0;
337 bool poll_until_activity_(uint32_t start, uint32_t timeout_ms, uint32_t &irq);
342 bool resolve_sync_race_(uint32_t start, uint32_t timeout_ms, uint32_t &irq,
RadioRxPacket &packet,
343 bool &early_completed);
346 bool try_early_completion_(
RadioRxPacket &packet, uint32_t sync_us, uint32_t irq_status, uint32_t start_ms,
347 uint32_t timeout_ms);
351 uint16_t response_preamble_;
352 uint16_t post_tx_settle_us_;
353 uint32_t busy_timeout_ms_;
380 bool preamble_latched_at_timeout_{
false};
RadioDriver(InternalGPIOPin *rst_pin=nullptr)
virtual uint32_t read_irq_status_raw()=0
Read the raw IRQ status word from the radio.
virtual void set_frequency_register(uint32_t freq_hz)=0
Set RF frequency via the chip's own frequency register/opcode encoding, and update current_freq_.
bool is_failed() const override
Returns true if the radio failed to initialize or encountered a fatal error.
void wait_busy_()
Wait until busy_pin_ reads low, feeding the watchdog while polling.
virtual void get_rx_buffer_status(uint8_t &reported_len, uint8_t &rx_offset)=0
Read the chip-reported RX length and buffer offset (raw, before any clamping).
bool is_preamble_detected() override
Check if preamble has been detected (while in RX).
virtual void read_rx_buffer(uint8_t offset, uint8_t *data, uint8_t len)=0
Read len bytes from the RX buffer starting at offset.
virtual bool read_rx_packet(RadioRxPacket &packet, bool blocking_wait, uint32_t irq_status)
Read a received packet from the buffer and return the raw bytes reported by the chip.
virtual uint32_t rx_done_bit() const =0
void rearm_rx_after_tx_()
Minimal path back into RX immediately after a transmission — see the definition for why this is delib...
SoftPhyDriverBase(InternalGPIOPin *rst_pin, InternalGPIOPin *busy_pin, uint32_t busy_timeout_ms, uint16_t default_response_preamble, uint16_t default_post_tx_settle_us)
bool is_sync_detected() override
Check if sync word has been detected (while in RX).
virtual uint32_t preamble_detected_bit() const =0
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.
virtual void configure_buffer_base()
Hook run as part of reset_rx_state_, before re-entering RX.
virtual void set_rx_packet_params()=0
Configure RX-specific packet parameters (preamble detector length, fixed probe length).
virtual uint32_t sync_word_valid_bit() const =0
virtual 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)=0
Populate the RadioCaptureInfo from chip-specific telemetry (RSSI opcode, packet-status byte,...
virtual void clear_irq_status(uint32_t irq_mask)=0
Clear IRQ status bits.
void set_post_tx_settle_us_(uint16_t delay_us)
Set the delay between TX completion and re-entering RX.
virtual void set_tx_packet_params(uint16_t preamble_len, uint8_t payload_len)=0
Configure TX packet parameters for one outgoing UART-encoded frame.
void reset_rx_state_(bool force_standby=true)
Reset RX state machine and buffer. Optionally force standby first.
virtual uint32_t tx_done_bit() const =0
bool failed_
Set on a BUSY timeout or a chip-identity check failing; see is_failed.
virtual uint8_t read_rssi_raw_byte()=0
Read the single raw RSSI byte (chip-specific opcode); formula is shared, see read_rssi.
int16_t read_rssi() override
Read instantaneous RSSI (in dBm) while in RX mode.
virtual void before_tx_arm()
Hook run immediately before every SetTx.
virtual void invalidate_stale_rx_content_after_tx()
Hook run from rearm_rx_after_tx_, after a transmission and before re-entering RX.
InternalGPIOPin * busy_pin_
BUSY line, read directly by both concrete drivers' own dump_debug() in addition to wait_busy_,...
uint16_t response_preamble() const override
Preamble for response/continuation frames — shared storage, see the concrete drivers' constructors/tu...
static constexpr uint8_t GFSK_PACKET_PARAMS_LEN
Byte count of the GFSK SetPacketParams payload — identical on both software-PHY chips.
virtual uint32_t idle_rx_completion_budget_ms() const
Blocking budget for the idle-path length-driven receive, in milliseconds (issue #81).
virtual void write_tx_buffer(const uint8_t *data, uint8_t len)=0
Write the UART-encoded TX payload into the chip's TX buffer.
void set_response_preamble_(uint16_t preamble)
Set the preamble length used for response/continuation frames within an exchange.
virtual int16_t early_rx_read_offset() const
Data-buffer offset an in-flight reception is being written to, or a negative value when this chip mus...
virtual uint32_t activity_irq_mask() const
IRQ bits that count as "activity" for the internal poll_until_activity_() helper and check_for_packet...
bool check_for_packet(RadioRxPacket &packet) override
Non-blocking check for a received packet.
bool wait_for_packet(RadioRxPacket &packet, uint32_t timeout_ms) override
Wait (blocking) for a packet with timeout.
bool send_packet(const uint8_t *data, uint8_t len, const RadioTxConfig &tx_config) override
Send a packet using the specified carrier frequency and preamble settings.
virtual void start_tx()=0
Issue the SetTx opcode with the fixed TX timeout — identical 3-byte payload on both chips,...
void change_frequency(uint32_t freq_hz) override
Change the carrier frequency using fast hop (no standby transition needed).
static constexpr uint8_t BITS_PER_BYTE
Number of bits in one protocol byte.
static constexpr uint8_t SOFT_PHY_RX_PROBE_PACKET_LEN
Fixed raw-RX probe length: chosen from captures of 23-25 byte protocol frames after UART packing and ...
constexpr uint32_t soft_phy_air_time_us(uint32_t raw_bytes)
On-air time in microseconds for raw_bytes bytes at the protocol's line rate.
constexpr uint32_t RX_HOP_HOLDOFF_US
Longest a frame arriving on the current channel may hold off an idle-path channel hop,...
static constexpr uint8_t SOFT_PHY_EARLY_HEADER_RAW_BYTES
Raw bytes read in the first stage of a length-driven receive — enough to hold CTRL0's UART cell (10 b...
static constexpr uint32_t SOFT_PHY_US_PER_SECOND
Microseconds in a second, for the air-time arithmetic below.
static constexpr uint32_t SOFT_PHY_IDLE_RX_COMPLETION_BUDGET_MS
Blocking budget SoftPhyDriverBase::check_for_packet gives a length-driven receive,...
static constexpr uint32_t SOFT_PHY_EARLY_MIN_WINDOW_MS
Smallest receive window a length-driven receive will be attempted in, in milliseconds.
static constexpr uint32_t SOFT_PHY_LINE_RATE_BPS
Protocol line rate. The same 38400 bps every driver programs into its own bitrate register.
static constexpr uint8_t SOFT_PHY_EARLY_READ_MARGIN_BYTES
Air-time margin added before every mid-reception buffer read, in raw bytes.
static constexpr uint32_t SOFT_PHY_EARLY_POLL_US
Poll interval while waiting out a frame's remaining air time, in microseconds.
static constexpr uint32_t SOFT_PHY_ALL_IRQ_BITS
Sentinel meaning "every IRQ bit counts as activity" — the default for SoftPhyDriverBase::activity_irq...
Radio abstraction layer for IO-Homecontrol.
Software PHY for radios without IoHomeOn hardware framing.
Raw packet received from the radio.
Configuration for transmitting a packet: carrier frequency and preamble length.
The GFSK SetPacketParams fields both software-PHY chips program identically.
uint16_t preamble_bytes
Byte-denominated, like every other preamble value in this codebase.
uint8_t crc_type
Chip-specific CRC-mode selector.
uint8_t payload_len
Configured payload length.
uint8_t sync_word_param
Chip-specific 24-bit sync-word selector.
uint8_t preamble_detector
Chip-specific detector-length selector.
uint8_t packet_type
Known-length / fixed-length selector.