use bitfield_struct::bitfield;
use crate::{CrcLength, DataRate, PaLevel};
use super::mnemonics;
#[bitfield(u8, order = Msb)]
pub(crate) struct ConfigReg {
#[bits(1)]
_padding: u8,
#[bits(1, access = None)]
pub rx_dr: bool,
#[bits(1, access = None)]
pub tx_ds: bool,
#[bits(1, access = None)]
pub tx_df: bool,
#[bits(2, access = None, default = 3)]
pub crc_length: u8,
pub power: bool,
pub is_rx: bool,
}
impl ConfigReg {
pub(crate) const CRC_MASK: u8 = 0b1100;
pub const fn crc_length(&self) -> CrcLength {
CrcLength::from_bits(self.into_bits() & Self::CRC_MASK)
}
pub fn with_crc_length(self, length: CrcLength) -> Self {
let new_val = self.into_bits() & !Self::CRC_MASK | length.into_bits();
Self::from_bits(new_val)
}
pub const fn rx_dr(&self) -> bool {
(self.into_bits() & mnemonics::MASK_RX_DR) == 0
}
pub fn with_rx_dr(self, enable: bool) -> Self {
Self::from_bits(
self.into_bits() & !mnemonics::MASK_RX_DR | ((!enable as u8) * mnemonics::MASK_RX_DR),
)
}
pub const fn tx_ds(&self) -> bool {
(self.into_bits() & mnemonics::MASK_TX_DS) == 0
}
pub fn with_tx_ds(self, enable: bool) -> Self {
Self::from_bits(
self.into_bits() & !mnemonics::MASK_TX_DS | ((!enable as u8) * mnemonics::MASK_TX_DS),
)
}
pub const fn tx_df(&self) -> bool {
(self.into_bits() & mnemonics::MASK_MAX_RT) == 0
}
pub fn with_tx_df(self, enable: bool) -> Self {
Self::from_bits(
self.into_bits() & !mnemonics::MASK_MAX_RT | ((!enable as u8) * mnemonics::MASK_MAX_RT),
)
}
pub fn as_rx(self) -> Self {
Self::from_bits(self.into_bits() | 1)
}
pub fn as_tx(self) -> Self {
Self::from_bits(self.into_bits() & !1)
}
}
#[bitfield(u8, order = Msb)]
pub(crate) struct SetupRetry {
#[bits(4, default = 5)]
pub ard: u8,
#[bits(4, default = 15)]
pub arc: u8,
}
#[bitfield(u8, order = Msb)]
pub(crate) struct SetupRfAw {
#[bits(2, access = None, default = 3)]
address_length: u8,
#[bits(3, access = None)]
data_rate: u8,
#[bits(2, access = None, default = 3)]
pa_level: u8,
#[bits(1, default = true)]
pub lna_enable: bool,
}
impl SetupRfAw {
const PA_MASK: u8 = 0b110;
const DATA_RATE_MASK: u8 = 0x28;
const ADDR_OFFSET: u8 = 6;
pub const fn address_length(&self) -> u8 {
(self.into_bits() >> Self::ADDR_OFFSET) + 2
}
pub fn with_address_length(self, length: u8) -> Self {
let new_val = self.into_bits() & !(0b11 << Self::ADDR_OFFSET);
Self::from_bits(new_val | ((length.clamp(2, 5) - 2) << Self::ADDR_OFFSET))
}
pub const fn data_rate(&self) -> DataRate {
DataRate::from_bits(self.into_bits() & Self::DATA_RATE_MASK)
}
pub fn with_data_rate(self, data_rate: DataRate) -> Self {
let new_val = self.into_bits() & !Self::DATA_RATE_MASK;
Self::from_bits(new_val | data_rate.into_bits())
}
pub const fn pa_level(&self) -> PaLevel {
PaLevel::from_bits(self.into_bits() & Self::PA_MASK)
}
pub fn with_pa_level(self, level: PaLevel) -> Self {
let new_val = self.into_bits() & !Self::PA_MASK;
Self::from_bits(new_val | level.into_bits())
}
}
#[bitfield(u8, order = Msb)]
pub(crate) struct Feature {
#[bits(3, access = WO)]
pub address_length: u8,
#[bits(1)]
_padding: u8,
pub is_plus_variant: bool,
#[bits(1, access = RO)]
pub dynamic_payloads: bool,
#[bits(1, access = RO)]
pub ack_payloads: bool,
pub ask_no_ack: bool,
}
impl Feature {
pub const REG_MASK: u8 = 7;
pub const fn address_length(&self) -> u8 {
self.into_bits() >> Self::ADDRESS_LENGTH_OFFSET
}
pub fn with_dynamic_payloads(self, enable: bool) -> Self {
let mut new_val = self.into_bits() & !(1u8 << Self::DYNAMIC_PAYLOADS_OFFSET);
if !enable {
new_val &= !(1u8 << Self::ACK_PAYLOADS_OFFSET);
} else {
new_val |= 1u8 << Self::DYNAMIC_PAYLOADS_OFFSET;
}
Self::from_bits(new_val)
}
pub fn with_ack_payloads(self, enable: bool) -> Self {
let mut new_value = self.into_bits() & !(1u8 << Self::ACK_PAYLOADS_OFFSET);
if enable {
new_value |= (1u8 << Self::ACK_PAYLOADS_OFFSET) | (1u8 << Self::DYNAMIC_PAYLOADS_OFFSET)
}
Self::from_bits(new_value)
}
}