1use core::mem::MaybeUninit;
26
27use capsules_core::alarm::AlarmDriver;
28use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
29use kernel::capabilities;
30use kernel::component::Component;
31use kernel::create_capability;
32use kernel::hil::time::{self, Alarm};
33
34#[macro_export]
36macro_rules! alarm_mux_component_static {
37 ($A:ty $(,)?) => {{
38 kernel::static_buf!(capsules_core::virtualizers::virtual_alarm::MuxAlarm<'static, $A>)
39 };};
40}
41
42#[macro_export]
44macro_rules! alarm_component_static {
45 ($A:ty $(,)?) => {{
46 let mux_alarm = kernel::static_buf!(
47 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>
48 );
49 let alarm_driver = kernel::static_buf!(
50 capsules_core::alarm::AlarmDriver<
51 'static,
52 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>,
53 >
54 );
55
56 (mux_alarm, alarm_driver)
57 };};
58}
59
60pub type AlarmDriverComponentType<A> = capsules_core::alarm::AlarmDriver<
61 'static,
62 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, A>,
63>;
64
65pub struct AlarmMuxComponent<A: 'static + time::Alarm<'static>> {
66 alarm: &'static A,
67}
68
69impl<A: 'static + time::Alarm<'static>> AlarmMuxComponent<A> {
70 pub fn new(alarm: &'static A) -> AlarmMuxComponent<A> {
71 AlarmMuxComponent { alarm }
72 }
73}
74
75impl<A: 'static + time::Alarm<'static>> Component for AlarmMuxComponent<A> {
76 type StaticInput = &'static mut MaybeUninit<MuxAlarm<'static, A>>;
77 type Output = &'static MuxAlarm<'static, A>;
78
79 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
80 let mux_alarm = static_buffer.write(MuxAlarm::new(self.alarm));
81
82 self.alarm.set_alarm_client(mux_alarm);
83 mux_alarm
84 }
85}
86
87pub struct AlarmDriverComponent<A: 'static + time::Alarm<'static>> {
88 board_kernel: &'static kernel::Kernel,
89 driver_num: usize,
90 alarm_mux: &'static MuxAlarm<'static, A>,
91}
92
93impl<A: 'static + time::Alarm<'static>> AlarmDriverComponent<A> {
94 pub fn new(
95 board_kernel: &'static kernel::Kernel,
96 driver_num: usize,
97 mux: &'static MuxAlarm<'static, A>,
98 ) -> AlarmDriverComponent<A> {
99 AlarmDriverComponent {
100 board_kernel,
101 driver_num,
102 alarm_mux: mux,
103 }
104 }
105}
106
107impl<A: 'static + time::Alarm<'static>> Component for AlarmDriverComponent<A> {
108 type StaticInput = (
109 &'static mut MaybeUninit<VirtualMuxAlarm<'static, A>>,
110 &'static mut MaybeUninit<AlarmDriver<'static, VirtualMuxAlarm<'static, A>>>,
111 );
112 type Output = &'static AlarmDriver<'static, VirtualMuxAlarm<'static, A>>;
113
114 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
115 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
116
117 let virtual_alarm1 = static_buffer.0.write(VirtualMuxAlarm::new(self.alarm_mux));
118 virtual_alarm1.setup();
119
120 let alarm = static_buffer.1.write(AlarmDriver::new(
121 virtual_alarm1,
122 self.board_kernel.create_grant(self.driver_num, &grant_cap),
123 ));
124
125 virtual_alarm1.set_alarm_client(alarm);
126 alarm
127 }
128}