lora_phy/
mod_params.rs

1pub use lora_modulation::{Bandwidth, CodingRate, SpreadingFactor};
2
3/// Errors types reported during LoRa physical layer processing
4#[allow(clippy::upper_case_acronyms)]
5#[derive(Debug, defmt::Format, PartialEq)]
6#[allow(missing_docs)]
7pub enum RadioError {
8    SPI,
9    Reset,
10    RfSwitchRx,
11    RfSwitchTx,
12    Busy,
13    Irq,
14    DIO1,
15    InvalidConfiguration,
16    InvalidRadioMode,
17    OpError(u8),
18    InvalidBaseAddress(usize, usize),
19    PayloadSizeUnexpected(usize),
20    PayloadSizeMismatch(usize, usize),
21    UnavailableSpreadingFactor,
22    UnavailableBandwidth,
23    InvalidBandwidthForFrequency,
24    InvalidSF6ExplicitHeaderRequest,
25    InvalidOutputPowerForFrequency,
26    TransmitTimeout,
27    ReceiveTimeout,
28    DutyCycleUnsupported,
29    RngUnsupported,
30}
31
32/// Status for a received packet
33#[derive(Clone, Copy)]
34#[allow(missing_docs)]
35pub struct PacketStatus {
36    pub rssi: i16,
37    pub snr: i16,
38}
39
40/// The state of the radio
41#[derive(Clone, Copy, defmt::Format, PartialEq)]
42pub enum RadioMode {
43    /// Sleep mode
44    Sleep,
45    /// Standby mode
46    Standby,
47    /// Frequency synthesis mode
48    FrequencySynthesis,
49    /// Transmit (TX) mode
50    Transmit,
51    /// Receive (RX) mode
52    Receive(RxMode),
53    /// Channel activity detection (CAD) mode
54    ChannelActivityDetection,
55}
56
57impl From<RxMode> for RadioMode {
58    fn from(rx_mode: RxMode) -> Self {
59        RadioMode::Receive(rx_mode)
60    }
61}
62
63/// Listening mode for LoRaWAN packet detection/reception
64#[derive(Clone, Copy, defmt::Format, PartialEq)]
65pub enum RxMode {
66    /// Single shot Rx Mode to listen until packet preamble is detected or RxTimeout occurs.
67    /// The device will stay in RX Mode until a packet is received.
68    /// Preamble length as symbols is configured via following registers:
69    /// sx126x: uses `SetLoRaSymbNumTimeout(0 < n < 255)` + `SetStopRxTimerOnPreamble(1)`
70    /// sx127x: uses `RegSymbTimeout (4 < n < 1023)`
71    // TODO: Single mode with time-based timeout is available on sx126x, but not sx127x
72    Single(u16),
73    /// Continuous Rx mode to listen for incoming packets continuously
74    Continuous,
75    /// Receive in Duty Cycle mode (NB! Not supported on sx127x)
76    DutyCycle(DutyCycleParams),
77}
78
79/// Modulation parameters for a send and/or receive communication channel
80pub struct ModulationParams {
81    pub(crate) spreading_factor: SpreadingFactor,
82    pub(crate) bandwidth: Bandwidth,
83    pub(crate) coding_rate: CodingRate,
84    pub(crate) low_data_rate_optimize: u8,
85    pub(crate) frequency_in_hz: u32,
86}
87
88/// Packet parameters for a send or receive communication channel
89pub struct PacketParams {
90    pub(crate) preamble_length: u16,  // number of LoRa symbols in the preamble
91    pub(crate) implicit_header: bool, // if the header is explicit, it will be transmitted in the LoRa packet, but is not transmitted if the header is implicit (known fixed length)
92    pub(crate) payload_length: u8,
93    pub(crate) crc_on: bool,
94    pub(crate) iq_inverted: bool,
95}
96
97impl PacketParams {
98    pub(crate) fn set_payload_length(&mut self, payload_length: usize) -> Result<(), RadioError> {
99        if payload_length > 255 {
100            return Err(RadioError::PayloadSizeUnexpected(payload_length));
101        }
102        self.payload_length = payload_length as u8;
103        Ok(())
104    }
105}
106
107/// Receive duty cycle parameters
108#[derive(Clone, Copy, defmt::Format, PartialEq)]
109pub struct DutyCycleParams {
110    /// receive interval
111    pub rx_time: u32,
112    /// sleep interval
113    pub sleep_time: u32,
114}