// use core::{ // cmp::{self, Ordering}, // convert::TryInto, // mem, // ops::Sub, // }; // // use cortex_m::peripheral::{SCB, SYST}; // use heapless::{binary_heap::Min, ArrayLength, BinaryHeap}; // // use crate::Monotonic; // // pub struct TimerQueue(pub BinaryHeap, N, Min>) // where // M: Monotonic, // ::Output: TryInto, // N: ArrayLength>, // T: Copy; // // impl TimerQueue // where // M: Monotonic, // ::Output: TryInto, // N: ArrayLength>, // T: Copy, // { // /// # Safety // /// // /// Writing to memory with a transmute in order to enable // /// interrupts of the SysTick timer // /// // /// Enqueue a task without checking if it is full // #[inline] // pub unsafe fn enqueue_unchecked(&mut self, nr: NotReady) { // let mut is_empty = true; // // Check if the top contains a non-empty element and if that element is // // greater than nr // let if_heap_max_greater_than_nr = self // .0 // .peek() // .map(|head| { // is_empty = false; // nr.instant < head.instant // }) // .unwrap_or(true); // if if_heap_max_greater_than_nr { // if is_empty { // mem::transmute::<_, SYST>(()).enable_interrupt(); // } // // // Set SysTick pending // SCB::set_pendst(); // } // // self.0.push_unchecked(nr); // } // // /// Dequeue a task from the TimerQueue // #[inline] // pub fn dequeue(&mut self) -> Option<(T, u8)> { // unsafe { // if let Some(instant) = self.0.peek().map(|p| p.instant) { // let now = M::now(); // // if instant < now { // // task became ready // let nr = self.0.pop_unchecked(); // // Some((nr.task, nr.index)) // } else { // // set a new timeout // const MAX: u32 = 0x00ffffff; // // let ratio = M::ratio(); // let dur = match (instant - now).try_into().ok().and_then(|x| { // x.checked_mul(ratio.numerator) // .map(|x| x / ratio.denominator) // }) { // None => MAX, // // // ARM Architecture Reference Manual says: // // "Setting SYST_RVR to zero has the effect of // // disabling the SysTick counter independently // // of the counter enable bit." // Some(0) => 1, // // Some(x) => cmp::min(MAX, x), // }; // mem::transmute::<_, SYST>(()).set_reload(dur); // // // Start counting down from the new reload // mem::transmute::<_, SYST>(()).clear_current(); // // None // } // } else { // // The queue is empty // mem::transmute::<_, SYST>(()).disable_interrupt(); // // None // } // } // } // } // // pub struct NotReady // where // T: Copy, // M: Monotonic, // ::Output: TryInto, // { // pub index: u8, // pub instant: M::Instant, // pub task: T, // } // // impl Eq for NotReady // where // T: Copy, // M: Monotonic, // ::Output: TryInto, // { // } // // impl Ord for NotReady // where // T: Copy, // M: Monotonic, // ::Output: TryInto, // { // fn cmp(&self, other: &Self) -> Ordering { // self.instant.cmp(&other.instant) // } // } // // impl PartialEq for NotReady // where // T: Copy, // M: Monotonic, // ::Output: TryInto, // { // fn eq(&self, other: &Self) -> bool { // self.instant == other.instant // } // } // // impl PartialOrd for NotReady // where // T: Copy, // M: Monotonic, // ::Output: TryInto, // { // fn partial_cmp(&self, other: &Self) -> Option { // Some(self.cmp(&other)) // } // }