/// System timer (SysTick) as a delay provider.
pub struct Delay {
    syst: SYST,
}

impl DelayNs for Delay {
    fn delay_ns(&mut self, ns: u32) {
        // The SysTick Reload Value register
        // supports values between 1 and 0x00FFFFFF.
        const MAX_RVR: u32 = 0x00FF_FFFF;

        let mut total_rvr: u32 = (u64::from(ns)
            * u64::from(HFCLK_FREQ) / 1_000_000_000)
            .try_into()
            .unwrap();

        while total_rvr != 0 {
            let current_rvr = if total_rvr <=
                                         MAX_RVR {
              total_rvr
            } else {
                MAX_RVR
            };

            self.syst.set_reload(current_rvr);
            self.syst.clear_current();
            self.syst.enable_counter();

            // Update the tracking variable
            // while we are waiting...
            total_rvr -= current_rvr;

            while !self.syst.has_wrapped() {}

            self.syst.disable_counter();
        }
    }
}
