1use capsules_core::button::Button;
36use core::mem::MaybeUninit;
37use kernel::capabilities;
38use kernel::component::Component;
39use kernel::create_capability;
40use kernel::hil::gpio;
41use kernel::hil::gpio::InterruptWithValue;
42
43#[macro_export]
44macro_rules! button_component_helper_owned {
45 ($Pin:ty, $(($P:expr, $M:expr, $F:expr)),+ $(,)?) => {
46 $crate::button_component_helper!(
47 $Pin,
48 $((
49 static_init!($Pin, $P),
50 $M,
51 $F
52 ),)*
53 )
54 };
55}
56
57#[macro_export]
58macro_rules! button_component_helper {
59 ($Pin:ty, $(($P:expr, $M:expr, $F:expr)),+ $(,)?) => {{
60 use kernel::static_init;
61 use kernel::count_expressions;
62 use kernel::hil::gpio::InterruptValueWrapper;
63 const NUM_BUTTONS: usize = count_expressions!($($P),+);
64
65 static_init!(
66 [(&'static InterruptValueWrapper<'static, $Pin>, kernel::hil::gpio::ActivationMode, kernel::hil::gpio::FloatingState); NUM_BUTTONS],
67 [
68 $(
69 (static_init!(InterruptValueWrapper<$Pin>, InterruptValueWrapper::new($P))
70 .finalize(),
71 $M,
72 $F
73 ),
74 )*
75 ]
76 )
77 };};
78}
79
80#[macro_export]
81macro_rules! button_component_static {
82 ($Pin:ty $(,)?) => {{
83 kernel::static_buf!(capsules_core::button::Button<'static, $Pin>)
84 };};
85}
86
87pub type ButtonComponentType<IP> = capsules_core::button::Button<'static, IP>;
88
89pub struct ButtonComponent<IP: 'static + gpio::InterruptPin<'static>> {
90 board_kernel: &'static kernel::Kernel,
91 driver_num: usize,
92 button_pins: &'static [(
93 &'static gpio::InterruptValueWrapper<'static, IP>,
94 gpio::ActivationMode,
95 gpio::FloatingState,
96 )],
97}
98
99impl<IP: 'static + gpio::InterruptPin<'static>> ButtonComponent<IP> {
100 pub fn new(
101 board_kernel: &'static kernel::Kernel,
102 driver_num: usize,
103 button_pins: &'static [(
104 &'static gpio::InterruptValueWrapper<'static, IP>,
105 gpio::ActivationMode,
106 gpio::FloatingState,
107 )],
108 ) -> Self {
109 Self {
110 board_kernel,
111 driver_num,
112 button_pins,
113 }
114 }
115}
116
117impl<IP: 'static + gpio::InterruptPin<'static>> Component for ButtonComponent<IP> {
118 type StaticInput = &'static mut MaybeUninit<Button<'static, IP>>;
119 type Output = &'static Button<'static, IP>;
120
121 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
122 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
123 let button = static_buffer.write(capsules_core::button::Button::new(
124 self.button_pins,
125 self.board_kernel.create_grant(self.driver_num, &grant_cap),
126 ));
127 for (pin, _, _) in self.button_pins.iter() {
128 pin.set_client(button);
129 }
130
131 button
132 }
133}