use core::cmp::Ordering; use core::marker::Unsize; use core::ptr; use cortex_m::peripheral::SYST; use heapless::binary_heap::{BinaryHeap, Min}; pub use heapless::ring_buffer::{Consumer, Producer, RingBuffer}; use untagged_option::UntaggedOption; pub struct TimerQueue where A: Unsize<[Message]>, { pub syst: SYST, pub queue: BinaryHeap, A, Min>, } impl TimerQueue where A: Unsize<[Message]>, { pub fn new(syst: SYST) -> Self { TimerQueue { syst, queue: BinaryHeap::new(), } } } #[derive(Clone, Copy)] pub struct Message { pub baseline: u32, pub task: T, pub payload: usize, } impl Message { pub fn new

(bl: u32, task: T, payload: Payload

) -> Self { Message { baseline: bl, task, payload: payload.erase(), } } } impl PartialEq for Message { fn eq(&self, other: &Self) -> bool { self.baseline.eq(&other.baseline) } } impl Eq for Message {} impl PartialOrd for Message { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for Message { fn cmp(&self, other: &Self) -> Ordering { (self.baseline as i32) .wrapping_sub(other.baseline as i32) .cmp(&0) } } pub struct Node where T: 'static, { data: UntaggedOption, next: Option<&'static mut Node>, } impl Node { pub const fn new() -> Self { Node { data: UntaggedOption::none(), next: None, } } } pub struct Payload where T: 'static, { node: &'static mut Node, } impl Payload { pub unsafe fn from(ptr: usize) -> Self { Payload { node: &mut *(ptr as *mut _), } } pub fn erase(self) -> usize { self.node as *mut _ as usize } pub fn read(self) -> (T, Slot) { unsafe { let payload = ptr::read(&self.node.data.some); (payload, Slot::new(self.node)) } } } pub struct Slot where T: 'static, { node: &'static mut Node, } impl Slot { pub fn new(node: &'static mut Node) -> Self { Slot { node } } pub fn write(self, data: T) -> Payload { unsafe { ptr::write(&mut self.node.data.some, data); Payload { node: self.node } } } } pub struct FreeList where T: 'static, { head: Option>, } impl FreeList { pub const fn new() -> Self { FreeList { head: None } } pub fn is_empty(&self) -> bool { self.head.is_none() } pub fn pop(&mut self) -> Option> { self.head.take().map(|head| { self.head = head.node.next.take().map(Slot::new); head }) } pub fn push(&mut self, free: Slot) { free.node.next = self.head.take().map(|slot| slot.node); self.head = Some(Slot::new(free.node)); } }