use crate::status::Status;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Precision {
Basic = 0,
High = 1,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum PulseShape {
None = 0,
Bt0p3 = 8,
Bt0p5 = 9,
Bt0p7 = 10,
Bt1p0 = 11,
Rc0p7 = 22,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum RxBw {
Bw4800 = 31,
Bw5800 = 23,
Bw7300 = 15,
Bw9700 = 30,
Bw11700 = 22,
Bw14600 = 14,
Bw19500 = 29,
Bw23400 = 21,
Bw29300 = 13,
Bw39000 = 28,
Bw46900 = 20,
Bw58600 = 12,
Bw78200 = 27,
Bw93800 = 19,
Bw117300 = 11,
Bw156200 = 26,
Bw187200 = 18,
Bw234300 = 10,
Bw312000 = 25,
Bw373600 = 17,
Bw467000 = 9,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum PblLenDetect {
None = 0,
Len8Bits = 4,
Len16Bits = 5,
Len24Bits = 6,
Len32Bits = 7,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum AddrComp {
Off = 0,
Node = 1,
NodeBcast = 2,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum FskPktFormat {
FixedLength = 0,
Variable8bit = 1,
Variable9bit = 2,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Crc {
CrcOff = 1,
Crc1Byte = 0,
Crc2Byte = 2,
Crc1ByteInv = 4,
Crc2ByteInv = 6,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum DcFree {
DcFreeOff = 0,
DcFreeWhitening = 1,
DcFreeSx128x = 3,
}
pub fn set_fsk_modulation_params_cmd(precision: Precision, bitrate: u32, pulse_shape: PulseShape, rx_bw: RxBw, fdev: u32) -> [u8; 12] {
let mut cmd = [0u8; 12];
cmd[0] = 0x02;
cmd[1] = 0x0F;
cmd[2] |= (precision as u8) & 0x1;
cmd[2] |= ((bitrate >> 24) & 0xFF) as u8;
cmd[3] |= ((bitrate >> 16) & 0xFF) as u8;
cmd[4] |= ((bitrate >> 8) & 0xFF) as u8;
cmd[5] |= (bitrate & 0xFF) as u8;
cmd[6] |= pulse_shape as u8;
cmd[7] |= rx_bw as u8;
cmd[8] |= ((fdev >> 24) & 0xFF) as u8;
cmd[9] |= ((fdev >> 16) & 0xFF) as u8;
cmd[10] |= ((fdev >> 8) & 0xFF) as u8;
cmd[11] |= (fdev & 0xFF) as u8;
cmd
}
#[allow(clippy::too_many_arguments)]
pub fn set_fsk_packet_params_cmd(pbl_len_tx: u16, pbl_len_detect: PblLenDetect, sync_word_len: u8, addr_comp: AddrComp, fsk_pkt_format: FskPktFormat, pld_len: u8, crc: Crc, dc_free: DcFree) -> [u8; 11] {
let mut cmd = [0u8; 11];
cmd[0] = 0x02;
cmd[1] = 0x10;
cmd[2] |= ((pbl_len_tx >> 8) & 0xFF) as u8;
cmd[3] |= (pbl_len_tx & 0xFF) as u8;
cmd[4] |= pbl_len_detect as u8;
cmd[5] |= sync_word_len;
cmd[6] |= (addr_comp as u8) & 0x3;
cmd[7] |= (fsk_pkt_format as u8) & 0x3;
cmd[8] |= pld_len;
cmd[9] |= crc as u8;
cmd[10] |= dc_free as u8;
cmd
}
pub fn set_fsk_sync_word_cmd(syncword: u64) -> [u8; 10] {
let mut cmd = [0u8; 10];
cmd[0] = 0x02;
cmd[1] = 0x06;
cmd[2] |= ((syncword >> 56) & 0xFF) as u8;
cmd[3] |= ((syncword >> 48) & 0xFF) as u8;
cmd[4] |= ((syncword >> 40) & 0xFF) as u8;
cmd[5] |= ((syncword >> 32) & 0xFF) as u8;
cmd[6] |= ((syncword >> 24) & 0xFF) as u8;
cmd[7] |= ((syncword >> 16) & 0xFF) as u8;
cmd[8] |= ((syncword >> 8) & 0xFF) as u8;
cmd[9] |= (syncword & 0xFF) as u8;
cmd
}
pub fn set_fsk_address_cmd(addr_node: u8, addr_bcast: u8) -> [u8; 4] {
let mut cmd = [0u8; 4];
cmd[0] = 0x02;
cmd[1] = 0x12;
cmd[2] |= addr_node;
cmd[3] |= addr_bcast;
cmd
}
pub fn set_fsk_crc_params_cmd(init: u32, polynom: u32) -> [u8; 10] {
let mut cmd = [0u8; 10];
cmd[0] = 0x02;
cmd[1] = 0x24;
cmd[2] |= ((init >> 24) & 0xFF) as u8;
cmd[3] |= ((init >> 16) & 0xFF) as u8;
cmd[4] |= ((init >> 8) & 0xFF) as u8;
cmd[5] |= (init & 0xFF) as u8;
cmd[6] |= ((polynom >> 24) & 0xFF) as u8;
cmd[7] |= ((polynom >> 16) & 0xFF) as u8;
cmd[8] |= ((polynom >> 8) & 0xFF) as u8;
cmd[9] |= (polynom & 0xFF) as u8;
cmd
}
pub fn set_fsk_whit_params_cmd(seed: u16) -> [u8; 4] {
let mut cmd = [0u8; 4];
cmd[0] = 0x02;
cmd[1] = 0x25;
cmd[2] |= ((seed >> 8) & 0xFF) as u8;
cmd[3] |= (seed & 0xFF) as u8;
cmd
}
pub fn get_fsk_packet_status_req() -> [u8; 2] {
[0x02, 0x04]
}
#[derive(Default)]
pub struct FskPacketStatusRsp([u8; 5]);
impl FskPacketStatusRsp {
pub fn new() -> Self {
Self::default()
}
pub fn status(&mut self) -> Status {
self.0[0].into()
}
pub fn rssi_sync(&self) -> u8 {
self.0[1]
}
pub fn rssi_avg(&self) -> u8 {
self.0[2]
}
pub fn rx_len(&self) -> u8 {
self.0[3]
}
pub fn addr_err(&self) -> bool {
(self.0[4] >> 5) & 0x1 != 0
}
pub fn crc_err(&self) -> bool {
(self.0[4] >> 4) & 0x1 != 0
}
pub fn len_err(&self) -> bool {
(self.0[4] >> 3) & 0x1 != 0
}
pub fn abort_err(&self) -> bool {
(self.0[4] >> 2) & 0x1 != 0
}
pub fn pkt_rcvd(&self) -> bool {
(self.0[4] >> 1) & 0x1 != 0
}
pub fn pkt_sent(&self) -> bool {
self.0[4] & 0x1 != 0
}
}
impl AsMut<[u8]> for FskPacketStatusRsp {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.0
}
}