Skip to main content

device_envoy_esp/led4/
output_array.rs

1#[cfg(target_os = "none")]
2use core::num::NonZeroU8;
3
4#[cfg(target_os = "none")]
5use esp_hal::gpio::{self, Level};
6
7#[cfg(target_os = "none")]
8use crate::Error::IndexOutOfBounds;
9#[cfg(target_os = "none")]
10use crate::Result;
11
12/// Array of GPIO output pins for LED displays.
13#[cfg(target_os = "none")]
14pub struct OutputArray<'a, const N: usize>([gpio::Output<'a>; N]);
15
16#[cfg(target_os = "none")]
17impl<'a, const N: usize> OutputArray<'a, N> {
18    /// Creates a new output array from GPIO pins.
19    #[must_use]
20    pub const fn new(outputs: [gpio::Output<'a>; N]) -> Self {
21        Self(outputs)
22    }
23
24    #[inline]
25    pub(crate) fn set_levels_at_indexes(&mut self, indexes: &[u8], level: Level) -> Result<()> {
26        for &index in indexes {
27            self.set_level_at_index(index, level)?;
28        }
29        Ok(())
30    }
31
32    #[inline]
33    pub(crate) fn set_level_at_index(&mut self, index: u8, level: Level) -> Result<()> {
34        self.get_mut(index as usize)
35            .ok_or(IndexOutOfBounds)?
36            .set_level(level);
37        Ok(())
38    }
39
40    #[inline]
41    pub(crate) fn get_mut(&mut self, index: usize) -> Option<&mut gpio::Output<'a>> {
42        self.0.get_mut(index)
43    }
44}
45
46#[cfg(target_os = "none")]
47impl OutputArray<'_, { u8::BITS as usize }> {
48    #[expect(clippy::shadow_reuse, reason = "Converting NonZeroU8 to u8")]
49    #[inline]
50    pub(crate) fn set_from_nonzero_bits(&mut self, bits: NonZeroU8) {
51        let mut bits = bits.get();
52        for output in &mut self.0 {
53            let level: Level = ((bits & 1) == 1).into();
54            output.set_level(level);
55            bits >>= 1;
56        }
57    }
58}