components/
adc.rs
1use capsules_core::adc::AdcDedicated;
8use capsules_core::adc::AdcVirtualized;
9use capsules_core::virtualizers::virtual_adc::{AdcDevice, MuxAdc};
10use core::mem::MaybeUninit;
11use kernel::capabilities;
12use kernel::component::Component;
13use kernel::create_capability;
14use kernel::hil::adc;
15
16#[macro_export]
17macro_rules! adc_mux_component_static {
18 ($A:ty $(,)?) => {{
19 kernel::static_buf!(capsules_core::virtualizers::virtual_adc::MuxAdc<'static, $A>)
20 };};
21}
22
23#[macro_export]
24macro_rules! adc_component_static {
25 ($A:ty $(,)?) => {{
26 kernel::static_buf!(capsules_core::virtualizers::virtual_adc::AdcDevice<'static, $A>)
27 };};
28}
29
30#[macro_export]
31macro_rules! adc_syscall_component_helper {
32 ($($P:expr),+ $(,)?) => {{
33 use kernel::count_expressions;
34 use kernel::static_init;
35 const NUM_DRIVERS: usize = count_expressions!($($P),+);
36
37 let drivers = static_init!(
38 [&'static dyn kernel::hil::adc::AdcChannel; NUM_DRIVERS],
39 [
40 $($P,)*
41 ]
42 );
43 let adc_virtualized = kernel::static_buf!(capsules_core::adc::AdcVirtualized<'static>);
44 (adc_virtualized, drivers)
45 };};
46}
47
48#[macro_export]
49macro_rules! adc_dedicated_component_static {
50 ($A:ty $(,)?) => {{
51 let adc = kernel::static_buf!(capsules_core::adc::AdcDedicated<'static, $A>);
52 let buffer1 = kernel::static_buf!([u16; capsules_core::adc::BUF_LEN]);
53 let buffer2 = kernel::static_buf!([u16; capsules_core::adc::BUF_LEN]);
54 let buffer3 = kernel::static_buf!([u16; capsules_core::adc::BUF_LEN]);
55
56 (adc, buffer1, buffer2, buffer3)
57 };};
58}
59
60pub struct AdcMuxComponent<A: 'static + adc::Adc<'static>> {
61 adc: &'static A,
62}
63
64impl<A: 'static + adc::Adc<'static>> AdcMuxComponent<A> {
65 pub fn new(adc: &'static A) -> Self {
66 AdcMuxComponent { adc }
67 }
68}
69
70impl<A: 'static + adc::Adc<'static>> Component for AdcMuxComponent<A> {
71 type StaticInput = &'static mut MaybeUninit<MuxAdc<'static, A>>;
72 type Output = &'static MuxAdc<'static, A>;
73
74 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
75 let adc_mux = static_buffer.write(MuxAdc::new(self.adc));
76
77 self.adc.set_client(adc_mux);
78
79 adc_mux
80 }
81}
82
83pub struct AdcComponent<A: 'static + adc::Adc<'static>> {
84 adc_mux: &'static MuxAdc<'static, A>,
85 channel: A::Channel,
86}
87
88impl<A: 'static + adc::Adc<'static>> AdcComponent<A> {
89 pub fn new(mux: &'static MuxAdc<'static, A>, channel: A::Channel) -> Self {
90 AdcComponent {
91 adc_mux: mux,
92 channel,
93 }
94 }
95}
96
97impl<A: 'static + adc::Adc<'static>> Component for AdcComponent<A> {
98 type StaticInput = &'static mut MaybeUninit<AdcDevice<'static, A>>;
99 type Output = &'static AdcDevice<'static, A>;
100
101 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
102 let adc_device = static_buffer.write(AdcDevice::new(self.adc_mux, self.channel));
103
104 adc_device.add_to_mux();
105
106 adc_device
107 }
108}
109
110pub struct AdcVirtualComponent {
111 board_kernel: &'static kernel::Kernel,
112 driver_num: usize,
113}
114
115impl AdcVirtualComponent {
116 pub fn new(board_kernel: &'static kernel::Kernel, driver_num: usize) -> AdcVirtualComponent {
117 AdcVirtualComponent {
118 board_kernel,
119 driver_num,
120 }
121 }
122}
123
124impl Component for AdcVirtualComponent {
125 type StaticInput = (
126 &'static mut MaybeUninit<AdcVirtualized<'static>>,
127 &'static [&'static dyn kernel::hil::adc::AdcChannel<'static>],
128 );
129 type Output = &'static capsules_core::adc::AdcVirtualized<'static>;
130
131 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
132 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
133 let grant_adc = self.board_kernel.create_grant(self.driver_num, &grant_cap);
134
135 let adc = static_buffer
136 .0
137 .write(capsules_core::adc::AdcVirtualized::new(
138 static_buffer.1,
139 grant_adc,
140 ));
141
142 for driver in static_buffer.1 {
143 kernel::hil::adc::AdcChannel::set_client(*driver, adc);
144 }
145
146 adc
147 }
148}
149
150pub type AdcDedicatedComponentType<A> = capsules_core::adc::AdcDedicated<'static, A>;
151
152pub struct AdcDedicatedComponent<
153 A: kernel::hil::adc::Adc<'static> + kernel::hil::adc::AdcHighSpeed<'static> + 'static,
154> {
155 adc: &'static A,
156 channels: &'static [A::Channel],
157 board_kernel: &'static kernel::Kernel,
158 driver_num: usize,
159}
160
161impl<A: kernel::hil::adc::Adc<'static> + kernel::hil::adc::AdcHighSpeed<'static> + 'static>
162 AdcDedicatedComponent<A>
163{
164 pub fn new(
165 adc: &'static A,
166 channels: &'static [A::Channel],
167 board_kernel: &'static kernel::Kernel,
168 driver_num: usize,
169 ) -> AdcDedicatedComponent<A> {
170 AdcDedicatedComponent {
171 adc,
172 channels,
173 board_kernel,
174 driver_num,
175 }
176 }
177}
178
179impl<A: kernel::hil::adc::Adc<'static> + kernel::hil::adc::AdcHighSpeed<'static> + 'static>
180 Component for AdcDedicatedComponent<A>
181{
182 type StaticInput = (
183 &'static mut MaybeUninit<AdcDedicated<'static, A>>,
184 &'static mut MaybeUninit<[u16; capsules_core::adc::BUF_LEN]>,
185 &'static mut MaybeUninit<[u16; capsules_core::adc::BUF_LEN]>,
186 &'static mut MaybeUninit<[u16; capsules_core::adc::BUF_LEN]>,
187 );
188 type Output = &'static AdcDedicated<'static, A>;
189
190 fn finalize(self, s: Self::StaticInput) -> Self::Output {
191 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
192
193 let buffer1 = s.1.write([0; capsules_core::adc::BUF_LEN]);
194 let buffer2 = s.2.write([0; capsules_core::adc::BUF_LEN]);
195 let buffer3 = s.3.write([0; capsules_core::adc::BUF_LEN]);
196
197 let adc = s.0.write(AdcDedicated::new(
198 self.adc,
199 self.board_kernel.create_grant(self.driver_num, &grant_cap),
200 self.channels,
201 buffer1,
202 buffer2,
203 buffer3,
204 ));
205 self.adc.set_client(adc);
206 self.adc.set_highspeed_client(adc);
207
208 adc
209 }
210}