use crate::{
app::{Addresses, EsbApp},
irq::{Disabled, EsbIrq, IrqTimer},
peripherals::{EsbRadio, EsbTimer, RADIO},
Config, Error,
};
use bbqueue::{ArrayLength, BBBuffer};
use core::{
marker::PhantomData,
sync::atomic::{AtomicBool, Ordering},
};
pub struct EsbBuffer<OutgoingLen, IncomingLen>
where
OutgoingLen: ArrayLength<u8>,
IncomingLen: ArrayLength<u8>,
{
pub app_to_radio_buf: BBBuffer<OutgoingLen>,
pub radio_to_app_buf: BBBuffer<IncomingLen>,
pub timer_flag: AtomicBool,
}
impl<OutgoingLen, IncomingLen> EsbBuffer<OutgoingLen, IncomingLen>
where
OutgoingLen: ArrayLength<u8>,
IncomingLen: ArrayLength<u8>,
{
#[allow(clippy::type_complexity)]
pub fn try_split<T: EsbTimer>(
&'static self,
timer: T,
radio: RADIO,
addresses: Addresses,
config: Config,
) -> Result<
(
EsbApp<OutgoingLen, IncomingLen>,
EsbIrq<OutgoingLen, IncomingLen, T, Disabled>,
IrqTimer<T>,
),
Error,
> {
let (atr_prod, atr_cons) = self
.app_to_radio_buf
.try_split_framed()
.map_err(|_| Error::AlreadySplit)?;
let (rta_prod, rta_cons) = self
.radio_to_app_buf
.try_split_framed()
.map_err(|_| Error::AlreadySplit)?;
self.timer_flag.store(false, Ordering::Release);
let app = EsbApp {
prod_to_radio: atr_prod,
cons_from_radio: rta_cons,
maximum_payload: config.maximum_payload_size,
};
let mut irq = EsbIrq {
prod_to_app: rta_prod,
cons_from_app: atr_cons,
timer,
radio: EsbRadio::new(radio),
state: Disabled,
addresses,
attempts: 0,
timer_flag: &self.timer_flag,
config,
};
let irq_timer = IrqTimer {
timer_flag: &self.timer_flag,
_timer: PhantomData,
};
irq.radio.init(
irq.config.maximum_payload_size,
irq.config.tx_power,
&irq.addresses,
);
irq.timer.init();
Ok((app, irq, irq_timer))
}
}