29#include <idfxx/future>
36#include <electro/decibel>
37#include <frequency/frequency>
120 [[nodiscard]] std::chrono::microseconds
time_on_air(
size_t payload_length)
const noexcept {
146 [[nodiscard]] std::optional<rx_duty_cycle>
rx_duty_cycle_for(uint16_t min_symbols = 8) const noexcept {
156#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
207 void start_listening(std::chrono::microseconds rx_period, std::chrono::microseconds sleep_period) {
338 if (rx_period <= std::chrono::microseconds::zero() || sleep_period <= std::chrono::microseconds::zero()) {
403 return error(f.error());
421 return error(r.error());
430#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
578 _packet_params = params;
597#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
617 template<
typename Rep,
typename Period>
618 void transmit(std::span<const uint8_t> data,
const std::chrono::duration<Rep, Period>&
timeout) {
631 template<
typename Rep,
typename Period>
667 template<
typename Rep,
typename Period>
672 return error(f.error());
674 return _await(*f, std::chrono::ceil<std::chrono::milliseconds>(
timeout));
691 template<
typename Rep,
typename Period>
696 return error(f.error());
698 return _await(*f, std::chrono::ceil<std::chrono::milliseconds>(
timeout));
705#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
847#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
919 [[nodiscard]] virtual
result<
void>
976 lora_packet_params _packet_params{};
994 auto late = f.
try_wait_for(std::chrono::milliseconds{0});
LoRa time-on-air (air-time) calculation.
result< T > try_wait_for(const std::chrono::duration< Rep, Period > &timeout) const
Blocks until the operation completes or the timeout expires.
result< T > try_wait() const
Blocks until the operation completes.
bool done() const noexcept
Non-blocking check for whether the operation has completed.
Abstract base class for LoRa radio transceivers.
static constexpr std::chrono::milliseconds scan_guard_window
Guard window for the blocking scan_channel.
rx_info read_received(std::span< uint8_t > buffer)
Reads the most recently received packet into the caller's buffer.
virtual result< void > do_standby()=0
Hook for try_standby.
result< void > try_set_frequency(freq::hertz hz)
Sets the RF carrier frequency.
result< cad_info > try_scan_channel()
Scans the channel for LoRa activity, blocking until the result is known.
void start_listening()
Starts continuous-receive mode.
idfxx::future< rx_info > start_receive(std::span< uint8_t > buffer)
Starts a single-shot receive into the caller's buffer.
result< electro::centi_dbm > try_current_rssi()
Returns the instantaneous RSSI on the configured channel.
static constexpr size_t max_payload_length
Maximum LoRa payload length in bytes.
result< bool > try_channel_busy()
Returns whether LoRa activity is currently detected on the channel.
chip_mode current_mode() const noexcept
Returns the radio's current high-level mode.
void start_listening(std::chrono::microseconds rx_period, std::chrono::microseconds sleep_period)
Starts duty-cycled (periodic) receive for low-power listening.
result< idfxx::future< rx_info > > try_start_receive(std::span< uint8_t > buffer)
Starts a single-shot receive into the caller's buffer.
virtual result< idfxx::future< void > > do_start_transmit(std::span< const uint8_t > data)=0
Hook for try_start_transmit.
result< void > try_sleep()
Puts the radio in its lowest-power sleep mode.
void sleep()
Puts the radio in its lowest-power sleep mode.
result< void > try_start_listening()
Starts continuous-receive mode.
virtual result< electro::centi_dbm > do_current_rssi()=0
Hook for try_current_rssi.
void set_packet_params(lora_packet_params params)
Configures the LoRa packet framing.
virtual std::chrono::microseconds do_rx_duty_cycle_min_sleep() const noexcept
Hook for rx_duty_cycle_for: the shortest sleep window worth duty-cycling for on this chip.
void transmit(std::span< const uint8_t > data)
Transmits a packet and blocks until completion, sizing the timeout automatically.
void start_listening(rx_duty_cycle cycle)
Starts duty-cycled (periodic) receive from precomputed windows.
result< void > try_set_packet_params(lora_packet_params params)
Configures the LoRa packet framing.
virtual result< void > do_set_frequency(freq::hertz hz)=0
Hook for try_set_frequency.
lora_packet_params packet_params() const noexcept
Returns the configured LoRa packet framing parameters.
result< void > try_start_listening(std::chrono::microseconds rx_period, std::chrono::microseconds sleep_period)
Starts duty-cycled (periodic) receive for low-power listening.
virtual result< void > do_set_modulation(lora_modulation mod)=0
Hook for try_set_modulation.
void set_modulation(lora_modulation mod)
Configures the LoRa modulation parameters.
void standby()
Puts the radio in standby mode.
result< void > try_start_listening(rx_duty_cycle cycle)
Starts duty-cycled (periodic) receive from precomputed windows.
std::chrono::microseconds time_on_air(size_t payload_length) const noexcept
Computes the time-on-air of a packet under the configured link parameters.
result< void > try_standby()
Puts the radio in standby mode.
result< idfxx::future< cad_info > > try_start_channel_scan()
Starts a one-shot channel-activity scan and returns a future.
result< void > try_transmit(std::span< const uint8_t > data, const std::chrono::duration< Rep, Period > &timeout)
Transmits a packet and blocks until completion.
electro::centi_dbm current_rssi()
Returns the instantaneous RSSI on the configured channel.
lora_transceiver & operator=(const lora_transceiver &)=delete
void start_listening(const std::optional< rx_duty_cycle > &cycle)
Starts duty-cycled receive, falling back to continuous receive.
idfxx::future< cad_info > start_channel_scan()
Starts a one-shot channel-activity scan and returns a future.
rx_info receive(std::span< uint8_t > buffer, const std::chrono::duration< Rep, Period > &timeout)
Receives a single packet, blocking until one arrives or the timeout expires.
void set_sync_word(lora_network network)
Selects the LoRa network by setting the sync word.
result< void > try_set_sync_word(lora_network network)
Selects the LoRa network by setting the sync word.
static constexpr std::chrono::milliseconds transmit_timeout_margin
Margin added to the packet's time-on-air when the blocking transmit overload without a timeout sizes ...
virtual result< rx_info > do_read_received(std::span< uint8_t > buffer)=0
Hook for try_read_received.
virtual result< idfxx::future< cad_info > > do_start_channel_scan()=0
Hook for try_start_channel_scan.
lora_transceiver()=default
virtual result< void > do_set_packet_params(lora_packet_params params)=0
Hook for try_set_packet_params.
packet_status last_packet_status()
Returns detailed status for the most recent packet.
virtual result< void > do_set_output_power(electro::dbm power, ramp_time ramp)=0
Hook for try_set_output_power.
lora_transceiver(lora_transceiver &&) noexcept=default
result< void > try_transmit(std::span< const uint8_t > data)
Transmits a packet and blocks until completion, sizing the timeout automatically.
void transmit(std::span< const uint8_t > data, const std::chrono::duration< Rep, Period > &timeout)
Transmits a packet and blocks until completion.
virtual result< idfxx::future< rx_info > > do_start_receive(std::span< uint8_t > buffer)=0
Hook for try_start_receive(std::span<uint8_t>) (single-shot receive).
result< void > try_start_listening(const std::optional< rx_duty_cycle > &cycle)
Starts duty-cycled receive, falling back to continuous receive.
result< void > try_set_output_power(electro::dbm power, ramp_time ramp=ramp_time::us_200)
Sets the transmit output power.
virtual result< void > do_set_sync_word(lora_network network)=0
Hook for try_set_sync_word.
std::optional< rx_duty_cycle > rx_duty_cycle_for(uint16_t min_symbols=8) const noexcept
Computes duty-cycle receive windows for the configured link parameters.
result< void > try_configure(const lora_link &link)
Applies a complete link configuration.
cad_info scan_channel()
Scans the channel for LoRa activity, blocking until the result is known.
virtual result< void > do_sleep()=0
Hook for try_sleep.
result< idfxx::future< void > > try_start_transmit(std::span< const uint8_t > data)
Starts a transmit and returns a future tracking its completion.
virtual result< void > do_start_listening()=0
Hook for try_start_listening() (continuous receive).
bool channel_busy()
Returns whether LoRa activity is currently detected on the channel.
void set_frequency(freq::hertz hz)
Sets the RF carrier frequency.
virtual ~lora_transceiver()=default
idfxx::future< void > start_transmit(std::span< const uint8_t > data)
Starts a transmit and returns a future tracking its completion.
void set_output_power(electro::dbm power, ramp_time ramp=ramp_time::us_200)
Sets the transmit output power.
virtual result< packet_status > do_last_packet_status()=0
Hook for try_last_packet_status.
result< rx_info > try_receive(std::span< uint8_t > buffer, const std::chrono::duration< Rep, Period > &timeout)
Receives a single packet, blocking until one arrives or the timeout expires.
virtual chip_mode do_current_mode() const noexcept=0
Hook for current_mode.
void configure(const lora_link &link)
Applies a complete link configuration.
result< packet_status > try_last_packet_status()
Returns detailed status for the most recent packet.
lora_modulation modulation() const noexcept
Returns the configured LoRa modulation parameters.
lora_transceiver(const lora_transceiver &)=delete
result< rx_info > try_read_received(std::span< uint8_t > buffer)
Reads the most recently received packet into the caller's buffer.
result< void > try_set_modulation(lora_modulation mod)
Configures the LoRa modulation parameters.
Duty-cycled receive window calculation.
Chip-agnostic LoRa modulation and packet types.
LoRa radio types and driver classes.
constexpr std::chrono::microseconds time_on_air(const lora_modulation &mod, const lora_packet_params &pkt, size_t payload_length) noexcept
Computes the time-on-air of a LoRa packet.
lora_network
LoRa network selection.
constexpr std::chrono::microseconds default_min_rx_sleep
Default shortest sleep window worth duty-cycling for.
ramp_time
Power-amplifier ramp-time bucket.
chip_mode
Top-level radio operating mode.
constexpr std::optional< rx_duty_cycle > rx_duty_cycle_for(const lora_modulation &mod, uint16_t sender_preamble, uint16_t min_symbols=8, std::chrono::microseconds min_sleep=default_min_rx_sleep) noexcept
Computes duty-cycle receive windows that cannot miss a packet.
constexpr std::unexpected< std::error_code > error(E e) noexcept
Creates an unexpected error from an error code enum.
T unwrap(result< T > result)
Throws a std::system_error if the result is an error.
@ timeout
Operation timed out.
@ not_supported
Operation or feature not supported.
@ invalid_arg
Invalid argument.
@ not_finished
Operation has not fully completed.
std::expected< T, std::error_code > result
result type wrapping a value or error code.
Result of a channel-activity-detection operation.
Complete LoRa link configuration.
lora_network network
Network (sync word) selection.
electro::dbm output_power
Transmit output power.
freq::hertz frequency
RF carrier frequency (required; no meaningful default).
lora_modulation modulation
Modulation parameters.
ramp_time ramp
Output-power ramp-up time.
lora_packet_params packet_params
Packet framing parameters.
LoRa modulation parameters.
LoRa packet framing parameters.
uint16_t preamble_length
Preamble length in symbols.
Detailed status for the most recent packet.
Listen/sleep windows for duty-cycled receive.
std::chrono::microseconds sleep_period
Time to sleep in each cycle.
std::chrono::microseconds rx_period
Time to listen in each cycle.
Information about a received packet.