1use capsules_core::virtualizers::virtual_pwm::{MuxPwm, PwmPinUser};
8use capsules_extra::pwm::Pwm;
9use core::mem::MaybeUninit;
10use kernel::capabilities;
11use kernel::component::Component;
12use kernel::create_capability;
13use kernel::hil::pwm;
14
15#[macro_export]
16macro_rules! pwm_mux_component_static {
17 ($A:ty $(,)?) => {{
18 kernel::static_buf!(capsules_core::virtualizers::virtual_pwm::MuxPwm<'static, $A>)
19 };};
20}
21
22#[macro_export]
23macro_rules! pwm_pin_user_component_static {
24 ($A:ty $(,)?) => {{
25 kernel::static_buf!(capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, $A>)
26 };};
27}
28
29#[macro_export]
30macro_rules! pwm_driver_component_helper {
31 ($($P:expr),+ $(,)?) => {{
32 use kernel::count_expressions;
33 use kernel::static_init;
34 const NUM_DRIVERS: usize = count_expressions!($($P),+);
35
36 let drivers = static_init!(
37 [&'static dyn kernel::hil::pwm::PwmPin; NUM_DRIVERS],
38 [
39 $($P,)*
40 ]
41 );
42 let pwm = kernel::static_buf!(capsules_extra::pwm::Pwm<'static, NUM_DRIVERS>);
43 (pwm, drivers)
44 };};
45}
46
47pub struct PwmMuxComponent<P: 'static + pwm::Pwm> {
48 pwm: &'static P,
49}
50
51impl<P: 'static + pwm::Pwm> PwmMuxComponent<P> {
52 pub fn new(pwm: &'static P) -> Self {
53 PwmMuxComponent { pwm }
54 }
55}
56
57impl<P: 'static + pwm::Pwm> Component for PwmMuxComponent<P> {
58 type StaticInput = &'static mut MaybeUninit<MuxPwm<'static, P>>;
59 type Output = &'static MuxPwm<'static, P>;
60
61 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
62 let pwm_mux = static_buffer.write(MuxPwm::new(self.pwm));
63
64 pwm_mux
65 }
66}
67
68pub struct PwmPinUserComponent<P: 'static + pwm::Pwm> {
69 pwm_mux: &'static MuxPwm<'static, P>,
70 channel: P::Pin,
71}
72
73impl<P: 'static + pwm::Pwm> PwmPinUserComponent<P> {
74 pub fn new(mux: &'static MuxPwm<'static, P>, channel: P::Pin) -> Self {
75 PwmPinUserComponent {
76 pwm_mux: mux,
77 channel,
78 }
79 }
80}
81
82impl<P: 'static + pwm::Pwm> Component for PwmPinUserComponent<P> {
83 type StaticInput = &'static mut MaybeUninit<PwmPinUser<'static, P>>;
84 type Output = &'static PwmPinUser<'static, P>;
85
86 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
87 let pwm_pin = static_buffer.write(PwmPinUser::new(self.pwm_mux, self.channel));
88
89 pwm_pin.add_to_mux();
90
91 pwm_pin
92 }
93}
94
95pub struct PwmDriverComponent<const NUM_PINS: usize> {
96 board_kernel: &'static kernel::Kernel,
97 driver_num: usize,
98}
99
100impl<const NUM_PINS: usize> PwmDriverComponent<NUM_PINS> {
101 pub fn new(
102 board_kernel: &'static kernel::Kernel,
103 driver_num: usize,
104 ) -> PwmDriverComponent<NUM_PINS> {
105 PwmDriverComponent {
106 board_kernel,
107 driver_num,
108 }
109 }
110}
111
112impl<const NUM_PINS: usize> Component for PwmDriverComponent<NUM_PINS> {
113 type StaticInput = (
114 &'static mut MaybeUninit<Pwm<'static, NUM_PINS>>,
115 &'static [&'static dyn kernel::hil::pwm::PwmPin; NUM_PINS],
116 );
117 type Output = &'static capsules_extra::pwm::Pwm<'static, NUM_PINS>;
118
119 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
120 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
121 let grant_adc = self.board_kernel.create_grant(self.driver_num, &grant_cap);
122
123 let pwm = static_buffer
124 .0
125 .write(capsules_extra::pwm::Pwm::new(static_buffer.1, grant_adc));
126
127 pwm
128 }
129}