components/
led.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Components for collections of LEDs.
6//!
7//! Usage
8//! -----
9//! ```rust
10//! let led = components::led::LedsComponent::new().finalize(components::led_component_static!(
11//!     kernel::hil::led::LedLow<'static, sam4l::gpio::GPIOPin>,
12//!     LedLow::new(&sam4l::gpio::PORT[LED_RED_PIN]),
13//!     LedLow::new(&sam4l::gpio::PORT[LED_GREEN_PIN]),
14//!     LedLow::new(&sam4l::gpio::PORT[LED_BLUE_PIN]),
15//! ));
16//! ```
17
18use capsules_core::led::LedDriver;
19use core::marker::PhantomData;
20use core::mem::MaybeUninit;
21use kernel::component::Component;
22use kernel::hil::led::Led;
23
24#[macro_export]
25macro_rules! led_component_static {
26    ($Led:ty, $($L:expr),+ $(,)?) => {{
27        use kernel::count_expressions;
28        use kernel::static_init;
29        const NUM_LEDS: usize = count_expressions!($($L),+);
30        let arr = static_init!(
31            [&'static $Led; NUM_LEDS],
32            [
33                $(
34                    static_init!(
35                        $Led,
36                        $L
37                    )
38                ),+
39            ]
40        );
41
42        let led = kernel::static_buf!( capsules_core::led::LedDriver<'static, $Led, NUM_LEDS>);
43        (led, arr)
44    };};
45}
46
47pub type LedsComponentType<L, const NUMLEDS: usize> = LedDriver<'static, L, NUMLEDS>;
48
49pub struct LedsComponent<L: 'static + Led, const NUM_LEDS: usize> {
50    _phantom: PhantomData<L>,
51}
52
53impl<L: 'static + Led, const NUM_LEDS: usize> LedsComponent<L, NUM_LEDS> {
54    pub fn new() -> Self {
55        Self {
56            _phantom: PhantomData,
57        }
58    }
59}
60
61impl<L: 'static + Led, const NUM_LEDS: usize> Component for LedsComponent<L, NUM_LEDS> {
62    type StaticInput = (
63        &'static mut MaybeUninit<LedDriver<'static, L, NUM_LEDS>>,
64        &'static mut [&'static L; NUM_LEDS],
65    );
66    type Output = &'static LedDriver<'static, L, NUM_LEDS>;
67
68    fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
69        static_buffer.0.write(LedDriver::new(static_buffer.1))
70    }
71}