284 lines
8.1 KiB
Rust
284 lines
8.1 KiB
Rust
use super::Ratio;
|
|
|
|
use super::Status;
|
|
|
|
/// (G)FSK packet status.
|
|
///
|
|
/// Returned by [`fsk_packet_status`].
|
|
///
|
|
/// [`fsk_packet_status`]: super::SubGhz::fsk_packet_status
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub struct FskPacketStatus {
|
|
buf: [u8; 4],
|
|
}
|
|
|
|
impl From<[u8; 4]> for FskPacketStatus {
|
|
fn from(buf: [u8; 4]) -> Self {
|
|
FskPacketStatus { buf }
|
|
}
|
|
}
|
|
|
|
impl FskPacketStatus {
|
|
/// Get the status.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// use stm32wl_hal::subghz::{CmdStatus, FskPacketStatus, Status, StatusMode};
|
|
///
|
|
/// let example_data_from_radio: [u8; 4] = [0x54, 0, 0, 0];
|
|
/// let pkt_status: FskPacketStatus = FskPacketStatus::from(example_data_from_radio);
|
|
/// let status: Status = pkt_status.status();
|
|
/// assert_eq!(status.mode(), Ok(StatusMode::Rx));
|
|
/// assert_eq!(status.cmd(), Ok(CmdStatus::Avaliable));
|
|
/// ```
|
|
pub const fn status(&self) -> Status {
|
|
Status::from_raw(self.buf[0])
|
|
}
|
|
|
|
/// Returns `true` if a preabmle error occured.
|
|
pub const fn preamble_err(&self) -> bool {
|
|
(self.buf[1] & (1 << 7)) != 0
|
|
}
|
|
|
|
/// Returns `true` if a synchronization error occured.
|
|
pub const fn sync_err(&self) -> bool {
|
|
(self.buf[1] & (1 << 6)) != 0
|
|
}
|
|
|
|
/// Returns `true` if an address error occured.
|
|
pub const fn addr_err(&self) -> bool {
|
|
(self.buf[1] & (1 << 5)) != 0
|
|
}
|
|
|
|
/// Returns `true` if an crc error occured.
|
|
pub const fn crc_err(&self) -> bool {
|
|
(self.buf[1] & (1 << 4)) != 0
|
|
}
|
|
|
|
/// Returns `true` if a length error occured.
|
|
pub const fn length_err(&self) -> bool {
|
|
(self.buf[1] & (1 << 3)) != 0
|
|
}
|
|
|
|
/// Returns `true` if an abort error occured.
|
|
pub const fn abort_err(&self) -> bool {
|
|
(self.buf[1] & (1 << 2)) != 0
|
|
}
|
|
|
|
/// Returns `true` if a packet is received.
|
|
pub const fn pkt_received(&self) -> bool {
|
|
(self.buf[1] & (1 << 1)) != 0
|
|
}
|
|
|
|
/// Returns `true` when a packet has been sent.
|
|
pub const fn pkt_sent(&self) -> bool {
|
|
(self.buf[1] & 1) != 0
|
|
}
|
|
|
|
/// Returns `true` if any error occured.
|
|
pub const fn any_err(&self) -> bool {
|
|
(self.buf[1] & 0xFC) != 0
|
|
}
|
|
|
|
/// RSSI level when the synchronization address is detected.
|
|
///
|
|
/// Units are in dBm.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// use stm32wl_hal::{subghz::FskPacketStatus, Ratio};
|
|
///
|
|
/// let example_data_from_radio: [u8; 4] = [0, 0, 80, 0];
|
|
/// let pkt_status: FskPacketStatus = FskPacketStatus::from(example_data_from_radio);
|
|
/// assert_eq!(pkt_status.rssi_sync().to_integer(), -40);
|
|
/// ```
|
|
pub fn rssi_sync(&self) -> Ratio<i16> {
|
|
Ratio::new_raw(i16::from(self.buf[2]), -2)
|
|
}
|
|
|
|
/// Return the RSSI level over the received packet.
|
|
///
|
|
/// Units are in dBm.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// use stm32wl_hal::{subghz::FskPacketStatus, Ratio};
|
|
///
|
|
/// let example_data_from_radio: [u8; 4] = [0, 0, 0, 100];
|
|
/// let pkt_status: FskPacketStatus = FskPacketStatus::from(example_data_from_radio);
|
|
/// assert_eq!(pkt_status.rssi_avg().to_integer(), -50);
|
|
/// ```
|
|
pub fn rssi_avg(&self) -> Ratio<i16> {
|
|
Ratio::new_raw(i16::from(self.buf[3]), -2)
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "defmt")]
|
|
impl defmt::Format for FskPacketStatus {
|
|
fn format(&self, fmt: defmt::Formatter) {
|
|
defmt::write!(
|
|
fmt,
|
|
r#"FskPacketStatus {{
|
|
status: {},
|
|
preamble_err: {},
|
|
sync_err: {},
|
|
addr_err: {},
|
|
crc_err: {},
|
|
length_err: {},
|
|
abort_err: {},
|
|
pkt_received: {},
|
|
pkt_sent: {},
|
|
rssi_sync: {},
|
|
rssi_avg: {},
|
|
}}"#,
|
|
self.status(),
|
|
self.preamble_err(),
|
|
self.sync_err(),
|
|
self.addr_err(),
|
|
self.crc_err(),
|
|
self.length_err(),
|
|
self.abort_err(),
|
|
self.pkt_received(),
|
|
self.pkt_sent(),
|
|
self.rssi_sync().to_integer(),
|
|
self.rssi_avg().to_integer()
|
|
)
|
|
}
|
|
}
|
|
|
|
impl core::fmt::Display for FskPacketStatus {
|
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
f.debug_struct("FskPacketStatus")
|
|
.field("status", &self.status())
|
|
.field("preamble_err", &self.preamble_err())
|
|
.field("sync_err", &self.sync_err())
|
|
.field("addr_err", &self.addr_err())
|
|
.field("crc_err", &self.crc_err())
|
|
.field("length_err", &self.length_err())
|
|
.field("abort_err", &self.abort_err())
|
|
.field("pkt_received", &self.pkt_received())
|
|
.field("pkt_sent", &self.pkt_sent())
|
|
.field("rssi_sync", &self.rssi_sync().to_integer())
|
|
.field("rssi_avg", &self.rssi_avg().to_integer())
|
|
.finish()
|
|
}
|
|
}
|
|
|
|
/// (G)FSK packet status.
|
|
///
|
|
/// Returned by [`lora_packet_status`].
|
|
///
|
|
/// [`lora_packet_status`]: super::SubGhz::lora_packet_status
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub struct LoRaPacketStatus {
|
|
buf: [u8; 4],
|
|
}
|
|
|
|
impl From<[u8; 4]> for LoRaPacketStatus {
|
|
fn from(buf: [u8; 4]) -> Self {
|
|
LoRaPacketStatus { buf }
|
|
}
|
|
}
|
|
|
|
impl LoRaPacketStatus {
|
|
/// Get the status.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// use stm32wl_hal::subghz::{CmdStatus, LoRaPacketStatus, Status, StatusMode};
|
|
///
|
|
/// let example_data_from_radio: [u8; 4] = [0x54, 0, 0, 0];
|
|
/// let pkt_status: LoRaPacketStatus = LoRaPacketStatus::from(example_data_from_radio);
|
|
/// let status: Status = pkt_status.status();
|
|
/// assert_eq!(status.mode(), Ok(StatusMode::Rx));
|
|
/// assert_eq!(status.cmd(), Ok(CmdStatus::Avaliable));
|
|
/// ```
|
|
pub const fn status(&self) -> Status {
|
|
Status::from_raw(self.buf[0])
|
|
}
|
|
|
|
/// Average RSSI level over the received packet.
|
|
///
|
|
/// Units are in dBm.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// use stm32wl_hal::{subghz::LoRaPacketStatus, Ratio};
|
|
///
|
|
/// let example_data_from_radio: [u8; 4] = [0, 80, 0, 0];
|
|
/// let pkt_status: LoRaPacketStatus = LoRaPacketStatus::from(example_data_from_radio);
|
|
/// assert_eq!(pkt_status.rssi_pkt().to_integer(), -40);
|
|
/// ```
|
|
pub fn rssi_pkt(&self) -> Ratio<i16> {
|
|
Ratio::new_raw(i16::from(self.buf[1]), -2)
|
|
}
|
|
|
|
/// Estimation of SNR over the received packet.
|
|
///
|
|
/// Units are in dB.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// use stm32wl_hal::{subghz::LoRaPacketStatus, Ratio};
|
|
///
|
|
/// let example_data_from_radio: [u8; 4] = [0, 0, 40, 0];
|
|
/// let pkt_status: LoRaPacketStatus = LoRaPacketStatus::from(example_data_from_radio);
|
|
/// assert_eq!(pkt_status.snr_pkt().to_integer(), 10);
|
|
/// ```
|
|
pub fn snr_pkt(&self) -> Ratio<i16> {
|
|
Ratio::new_raw(i16::from(self.buf[2]), 4)
|
|
}
|
|
|
|
/// Estimation of RSSI level of the LoRa signal after despreading.
|
|
///
|
|
/// Units are in dBm.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// use stm32wl_hal::{subghz::LoRaPacketStatus, Ratio};
|
|
///
|
|
/// let example_data_from_radio: [u8; 4] = [0, 0, 0, 80];
|
|
/// let pkt_status: LoRaPacketStatus = LoRaPacketStatus::from(example_data_from_radio);
|
|
/// assert_eq!(pkt_status.signal_rssi_pkt().to_integer(), -40);
|
|
/// ```
|
|
pub fn signal_rssi_pkt(&self) -> Ratio<i16> {
|
|
Ratio::new_raw(i16::from(self.buf[3]), -2)
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "defmt")]
|
|
impl defmt::Format for LoRaPacketStatus {
|
|
fn format(&self, fmt: defmt::Formatter) {
|
|
defmt::write!(
|
|
fmt,
|
|
r#"LoRaPacketStatus {{
|
|
status: {},
|
|
rssi_pkt: {},
|
|
snr_pkt: {},
|
|
signal_rssi_pkt: {},
|
|
}}"#,
|
|
self.status(),
|
|
self.rssi_pkt().to_integer(),
|
|
self.snr_pkt().to_integer(),
|
|
self.signal_rssi_pkt().to_integer(),
|
|
)
|
|
}
|
|
}
|
|
|
|
impl core::fmt::Display for LoRaPacketStatus {
|
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
f.debug_struct("LoRaPacketStatus")
|
|
.field("status", &self.status())
|
|
.field("rssi_pkt", &self.rssi_pkt().to_integer())
|
|
.field("snr_pkt", &self.snr_pkt().to_integer())
|
|
.field("signal_rssi_pkt", &self.signal_rssi_pkt().to_integer())
|
|
.finish()
|
|
}
|
|
}
|