lr2021/
flrc.rs

1//! # API related to FLRC operations
2//!
3//! This module provides an API for configuring and operating the LR2021 chip for Fast Long-Range Communication (FLRC).
4//! FLRC is a Semtech proprietary protocol using GMSK modulation, offering higher sensitivity compared to BLE.
5//! It supports configurable bitrates, coding rates, and filtering on syncwords accepting up to 3 values on 32 bits.
6//!
7//! ## Quick Start
8//!
9//! Here's a typical sequence to initialize the chip for FLRC operations:
10//!
11//! ```rust,no_run
12//! use lr2021::radio::PacketType;
13//! use lr2021::flrc::{FlrcBitrate, FlrcCr, FlrcPacketParams, AgcPblLen, SwLen, SwTx, SwMatch, PktFormat, Crc};
14//! use lr2021::PulseShape;
15//!
16//! // Set packet type to FLRC
17//! lr2021.set_packet_type(PacketType::Flrc).await.expect("Setting packet type");
18//!
19//! // Configure FLRC modulation (2.6Mbps, no coding, BT=1.0 pulse shaping)
20//! lr2021.set_flrc_modulation(FlrcBitrate::Br2600, FlrcCr::None, PulseShape::Bt1p0)
21//!     .await.expect("Setting FLRC modulation");
22//!
23//! // Configure syncwords (up to 3 can be configured)
24//! lr2021.set_flrc_syncword(1, 0xCD05CAFE, true).await.expect("Setting syncword 1");
25//! lr2021.set_flrc_syncword(2, 0x12345678, true).await.expect("Setting syncword 2");
26//! lr2021.set_flrc_syncword(3, 0x9ABCDEF0, true).await.expect("Setting syncword 3");
27//!
28//! // Configure packet parameters
29//! let flrc_params = FlrcPacketParams::new(
30//!     AgcPblLen::Len16Bits,    // 16-bit preamble
31//!     SwLen::Sw32b,            // 32-bit syncword length
32//!     SwTx::Sw1,               // Use syncword 1 for TX
33//!     SwMatch::Match123,       // Match any of the 3 syncwords on RX
34//!     PktFormat::Dynamic,      // Dynamic packet length
35//!     Crc::Crc24,             // 24-bit CRC
36//!     255                      // Max payload length
37//! );
38//! lr2021.set_flrc_packet(&flrc_params).await.expect("Setting packet parameters");
39//! ```
40//!
41//! ## Available Methods
42//!
43//! - [`set_flrc_modulation`](Lr2021::set_flrc_modulation) - Configure bitrate, coding rate and pulse shaping
44//! - [`set_flrc_packet`](Lr2021::set_flrc_packet) - Set packet parameters (preamble, syncword, CRC, length)
45//! - [`set_flrc_syncword`](Lr2021::set_flrc_syncword) - Configure one of the three possible syncwords
46//! - [`get_flrc_packet_status`](Lr2021::get_flrc_packet_status) - Get status of last received packet
47//! - [`get_flrc_rx_stats`](Lr2021::get_flrc_rx_stats) - Get basic reception statistics
48
49use embedded_hal::digital::OutputPin;
50use embedded_hal_async::spi::SpiBus;
51
52pub use super::cmd::cmd_flrc::*;
53use super::{BusyPin, Lr2021, Lr2021Error, PulseShape};
54
55pub struct FlrcPacketParams {
56    pub agc_pbl_len: AgcPblLen,
57    pub sw_len: SwLen,
58    pub sw_tx: SwTx,
59    pub sw_match: SwMatch,
60    pub hdr_format: PktFormat,
61    pub crc: Crc,
62    pub pld_len: u16
63}
64
65impl FlrcPacketParams {
66    pub fn new(agc_pbl_len: AgcPblLen, sw_len: SwLen, sw_tx: SwTx, sw_match: SwMatch, hdr_format: PktFormat, crc: Crc, pld_len: u16) -> Self {
67        Self{agc_pbl_len, sw_len, sw_tx, sw_match, hdr_format, crc, pld_len}
68    }
69}
70
71impl<O,SPI, M> Lr2021<O,SPI, M> where
72    O: OutputPin, SPI: SpiBus<u8>, M: BusyPin
73{
74
75    /// Set Modulation parameters: raw bitrate, coding rate and pulse shaping
76    pub async fn set_flrc_modulation(&mut self, bitrate: FlrcBitrate, cr: FlrcCr, pulse_shape: PulseShape) -> Result<(), Lr2021Error> {
77        let req = set_flrc_modulation_params_cmd(bitrate, cr, pulse_shape);
78        self.cmd_wr(&req).await
79    }
80
81    /// Set FLRC packet parameters: preamble, syncword, header implicit/explicit, CRC and packet length (max 511)
82    pub async fn set_flrc_packet(&mut self, params: &FlrcPacketParams) -> Result<(), Lr2021Error> {
83        let req = set_flrc_packet_params_cmd(
84            params.agc_pbl_len,
85            params.sw_len,
86            params.sw_tx,
87            params.sw_match,
88            params.hdr_format,
89            params.crc,
90            params.pld_len);
91        self.cmd_wr(&req).await
92    }
93
94    /// Configure one of the three possible syncword
95    pub async fn set_flrc_syncword(&mut self, sw_num: u8, syncword: u32, is_16b: bool) -> Result<(), Lr2021Error> {
96        let sw = if is_16b {syncword << 16} else {syncword};
97        let req = set_flrc_syncword_cmd(sw_num, sw);
98        let req_s = if is_16b {&req[..5]} else {&req};
99        self.cmd_wr(req_s).await
100    }
101
102    /// Return length of last packet received
103    pub async fn get_flrc_packet_status(&mut self) -> Result<FlrcPacketStatusRsp, Lr2021Error> {
104        let req = get_flrc_packet_status_req();
105        let mut rsp = FlrcPacketStatusRsp::new();
106        self.cmd_rd(&req, rsp.as_mut()).await?;
107        Ok(rsp)
108    }
109
110    /// Return basic RX stats
111    pub async fn get_flrc_rx_stats(&mut self) -> Result<FlrcRxStatsRsp, Lr2021Error> {
112        let req = get_flrc_rx_stats_req();
113        let mut rsp = FlrcRxStatsRsp::new();
114        self.cmd_rd(&req, rsp.as_mut()).await?;
115        Ok(rsp)
116    }
117
118}