atsamd_hal/
delay.rs
1use atsamd_hal_macros::hal_cfg;
4use cortex_m::peripheral::syst::SystClkSource;
5use cortex_m::peripheral::SYST;
6
7use crate::clock::GenericClockController;
8use crate::ehal::delay::DelayNs;
9use crate::ehal_02;
10use crate::time::Hertz;
11
12#[hal_cfg("rtc-d5x")]
13use crate::typelevel::Increment;
14
15#[hal_cfg("rtc-d5x")]
16use crate::clock::v2::{gclk::Gclk0Id, Source};
17
18pub struct Delay {
20 sysclock: Hertz,
21 syst: SYST,
22}
23
24impl Delay {
25 pub fn new(mut syst: SYST, clocks: &mut GenericClockController) -> Self {
27 syst.set_clock_source(SystClkSource::Core);
28
29 Delay {
30 syst,
31 sysclock: clocks.gclk0().into(),
32 }
33 }
34
35 #[hal_cfg("rtc-d5x")]
36 pub fn new_with_source<S>(mut syst: SYST, gclk0: S) -> (Self, S::Inc)
39 where
40 S: Source<Id = Gclk0Id> + Increment,
41 {
42 syst.set_clock_source(SystClkSource::Core);
43 (
44 Delay {
45 syst,
46 sysclock: gclk0.freq(),
47 },
48 gclk0.inc(),
49 )
50 }
51
52 pub fn free(self) -> SYST {
54 self.syst
55 }
56}
57
58impl DelayNs for Delay {
59 fn delay_ns(&mut self, ns: u32) {
64 self.delay_us(ns / 1000);
65 }
66
67 fn delay_us(&mut self, us: u32) {
68 const MAX_RVR: u32 = 0x00FF_FFFF;
70
71 let mut total_rvr = us * (self.sysclock.to_Hz() / 1_000_000);
72
73 while total_rvr != 0 {
74 let current_rvr = if total_rvr <= MAX_RVR {
75 total_rvr
76 } else {
77 MAX_RVR
78 };
79
80 self.syst.set_reload(current_rvr);
81 self.syst.clear_current();
82 self.syst.enable_counter();
83
84 total_rvr -= current_rvr;
86
87 while !self.syst.has_wrapped() {}
88
89 self.syst.disable_counter();
90 }
91 }
92
93 fn delay_ms(&mut self, ms: u32) {
94 self.delay_us(ms * 1000);
95 }
96}
97
98impl ehal_02::blocking::delay::DelayMs<u32> for Delay {
99 fn delay_ms(&mut self, ms: u32) {
100 <Self as DelayNs>::delay_us(self, ms * 1_000);
101 }
102}
103
104impl ehal_02::blocking::delay::DelayMs<u16> for Delay {
105 fn delay_ms(&mut self, ms: u16) {
106 <Self as ehal_02::blocking::delay::DelayMs<u32>>::delay_ms(self, ms as u32);
107 }
108}
109
110impl ehal_02::blocking::delay::DelayMs<u8> for Delay {
111 fn delay_ms(&mut self, ms: u8) {
112 <Self as ehal_02::blocking::delay::DelayMs<u32>>::delay_ms(self, ms as u32);
113 }
114}
115
116impl ehal_02::blocking::delay::DelayUs<u32> for Delay {
117 fn delay_us(&mut self, us: u32) {
118 <Self as DelayNs>::delay_us(self, us);
119 }
120}
121
122impl ehal_02::blocking::delay::DelayUs<u16> for Delay {
123 fn delay_us(&mut self, us: u16) {
124 <Self as ehal_02::blocking::delay::DelayUs<u32>>::delay_us(self, us as u32);
125 }
126}
127
128impl ehal_02::blocking::delay::DelayUs<u8> for Delay {
129 fn delay_us(&mut self, us: u8) {
130 <Self as ehal_02::blocking::delay::DelayUs<u32>>::delay_us(self, us as u32);
131 }
132}