1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use core::num::NonZeroUsize;
use r3_core::{
closure::Closure,
kernel::raw_cfg::{CfgTimer, TimerDescriptor},
utils::Init,
};
use crate::{cfg::CfgBuilder, klock::CpuLockCell, timeout, timer, KernelTraits, Port};
unsafe impl<Traits: KernelTraits> const CfgTimer for CfgBuilder<Traits> {
fn timer_define<Properties: ~const r3_core::bag::Bag>(
&mut self,
TimerDescriptor {
phantom: _,
period,
delay,
active,
start,
}: TimerDescriptor<Self::System>,
_properties: Properties,
) -> timer::TimerId {
let period = if let Some(period) = period {
if let Ok(x) = timeout::time32_from_duration(period) {
x
} else {
panic!("`period` must not be negative");
}
} else {
timeout::BAD_DURATION32
};
let delay = if let Some(delay) = delay {
if let Ok(x) = timeout::time32_from_duration(delay) {
x
} else {
panic!("`delay` must not be negative");
}
} else {
timeout::BAD_DURATION32
};
self.timers.push(CfgBuilderTimer {
start,
delay,
period,
active,
});
unsafe { NonZeroUsize::new_unchecked(self.timers.len()) }
}
}
#[doc(hidden)]
pub struct CfgBuilderTimer {
start: Closure,
delay: timeout::Time32,
period: timeout::Time32,
active: bool,
}
impl Clone for CfgBuilderTimer {
fn clone(&self) -> Self {
Self {
start: self.start,
delay: self.delay,
period: self.period,
active: self.active,
}
}
}
impl Copy for CfgBuilderTimer {}
impl CfgBuilderTimer {
pub const fn to_state<Traits: KernelTraits>(
&self,
attr: &'static timer::TimerAttr<Traits>,
i: usize,
) -> timer::TimerCb<Traits> {
let timeout = timeout::Timeout::new(timer::timer_timeout_handler::<Traits>, i);
let timeout = if self.delay == timeout::BAD_DURATION32 {
timeout.with_at_raw(self.delay)
} else {
timeout.with_expiration_at(self.delay)
};
timer::TimerCb {
attr,
timeout,
period: CpuLockCell::new(self.period),
active: CpuLockCell::new(false),
}
}
pub const fn to_attr<Traits: Port>(&self) -> timer::TimerAttr<Traits> {
timer::TimerAttr {
entry_point: self.start,
init_active: self.active,
_phantom: Init::INIT,
}
}
}