1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
use imxrt_hal as hal;

use hal::iomuxc::{self, flexio::Pin};

use paste::paste;

/// The pins to use for WS2812.
pub trait Pins<const N: u8, const L: usize> {
    /// The amount of pins this object contains.
    const PIN_COUNT: u8;

    /// Configures the pins.
    ///
    /// This is not intended to be called by the user;
    /// it will be used inside of the driver.
    fn configure(&mut self);

    /// The FlexIO pin offsets
    const FLEXIO_PIN_OFFSETS: &'static [u8];
}

macro_rules! count {
    () => (0u8);
    ( $x:tt $($xs:tt)* ) => (1u8 + count!($($xs)*));
}

macro_rules! impl_pins {
    ($($n:literal)+) => {
        paste! {
            impl<const N: u8, $([<P $n>]: Pin<N>),+> Pins<N, {count!($($n)+) as usize}> for ($([<P $n>]),+,) {
                fn configure(&mut self) {
                    $(
                        iomuxc::flexio::prepare(&mut self.$n);
                    )+
                }

                const PIN_COUNT: u8 = count!($($n)+);

                const FLEXIO_PIN_OFFSETS: &'static[u8] = &[$(
                    [<P $n>]::OFFSET
                ),+];
            }
        }
    };
}

impl_pins!(0);
impl_pins!(0 1);
impl_pins!(0 1 2);
impl_pins!(0 1 2 3);