use crate::{
Element, Error,
channel::{self, Channel},
interrupt::Transfer,
};
use core::{
future::Future,
pin::Pin,
task::{Context, Poll},
};
pub struct Memcpy<'a, E> {
transfer: Transfer<'a>,
channel: &'a Channel,
_elem: core::marker::PhantomData<(&'a E, &'a mut E)>,
}
pub fn memcpy<'a, E: Element>(
source: &'a [E],
destination: &'a mut [E],
channel: &'a mut Channel,
) -> Memcpy<'a, E> {
channel.disable();
channel.set_disable_on_completion(true);
unsafe {
channel::set_source_linear_buffer(channel, source);
channel::set_destination_linear_buffer(channel, destination);
}
channel.set_channel_configuration(channel::Configuration::Off);
unsafe {
channel.set_minor_loop_bytes(
core::mem::size_of::<E>().saturating_mul(source.len().min(destination.len())) as u32,
);
channel.set_transfer_iterations(1);
}
Memcpy {
transfer: unsafe { Transfer::new(channel) },
channel,
_elem: core::marker::PhantomData,
}
}
impl<E> Future for Memcpy<'_, E> {
type Output = Result<(), Error>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let transfer = unsafe { self.as_mut().map_unchecked_mut(|this| &mut this.transfer) };
let poll = transfer.poll(cx);
if poll.is_pending() && !self.channel.is_active() {
self.channel.start();
}
poll
}
}