use crate::interface::Interface;
use crate::low_level::LowLevel;
use crate::models::Model;
use crate::registers::Register;
pub trait Waiter<M: Model, I: Interface> {
type Error;
fn wait_for_space(
&mut self,
ell: &mut LowLevel<M, I>,
need: u16,
) -> core::result::Result<u16, WaiterError<Self::Error>>;
}
#[derive(Debug)]
pub enum WaiterError<E: Sized> {
Comm(E),
Fault,
}
fn waiter_comm_result<R, E: Sized>(
result: core::result::Result<R, E>,
) -> core::result::Result<R, WaiterError<E>> {
match result {
Ok(v) => Ok(v),
Err(err) => Err(WaiterError::Comm(err)),
}
}
pub struct PollingWaiter<M: Model, I: Interface> {
_ei: core::marker::PhantomData<I>,
_m: core::marker::PhantomData<M>,
}
impl<M: Model, I: Interface> PollingWaiter<M, I> {
pub(crate) fn new() -> Self {
Self {
_ei: core::marker::PhantomData,
_m: core::marker::PhantomData,
}
}
}
impl<M: Model, I: Interface> Waiter<M, I> for PollingWaiter<M, I> {
type Error = crate::error::Error<I>;
fn wait_for_space(
&mut self,
ell: &mut LowLevel<M, I>,
need: u16,
) -> core::result::Result<u16, WaiterError<Self::Error>> {
loop {
let known_space = waiter_comm_result(ell.rd16(ell.reg_ptr(Register::CMDB_SPACE)))?;
if (known_space % 4) != 0 {
return Err(WaiterError::Fault);
}
if known_space >= need {
return Ok(known_space);
}
}
}
}