use core::sync::atomic::{compiler_fence, Ordering};
use super::{
single_channel::ChannelConfig, single_channel::SingleChannel, Pace, ReadTarget, WriteTarget,
};
pub struct Config<CH: SingleChannel, FROM: ReadTarget, TO: WriteTarget> {
ch: CH,
from: FROM,
to: TO,
pace: Pace,
}
impl<CH, FROM, TO, WORD> Config<CH, FROM, TO>
where
CH: SingleChannel,
FROM: ReadTarget<ReceivedWord = WORD>,
TO: WriteTarget<TransmittedWord = WORD>,
{
pub fn new(ch: CH, from: FROM, to: TO) -> Config<CH, FROM, TO> {
Config {
ch,
from,
to,
pace: Pace::PreferSource,
}
}
pub fn pace(&mut self, pace: Pace) {
self.pace = pace;
}
pub fn start(mut self) -> Transfer<CH, FROM, TO> {
cortex_m::asm::dsb();
compiler_fence(Ordering::SeqCst);
self.ch
.config(&self.from, &mut self.to, self.pace, None, true);
Transfer {
ch: self.ch,
from: self.from,
to: self.to,
}
}
}
pub struct Transfer<CH: SingleChannel, FROM: ReadTarget, TO: WriteTarget> {
ch: CH,
from: FROM,
to: TO,
}
impl<CH, FROM, TO, WORD> Transfer<CH, FROM, TO>
where
CH: SingleChannel,
FROM: ReadTarget<ReceivedWord = WORD>,
TO: WriteTarget<TransmittedWord = WORD>,
{
pub fn check_irq0(&mut self) -> bool {
self.ch.check_irq0()
}
pub fn check_irq1(&mut self) -> bool {
self.ch.check_irq1()
}
pub fn is_done(&self) -> bool {
!self.ch.ch().ch_ctrl_trig.read().busy().bit_is_set()
}
pub fn wait(self) -> (CH, FROM, TO) {
while !self.is_done() {}
cortex_m::asm::dsb();
compiler_fence(Ordering::SeqCst);
(self.ch, self.from, self.to)
}
}