apa102_spi/
pixel.rs

1use smart_leds_trait::{RGB16, RGB8};
2use ux::u5;
3
4/// A single APA102 pixel: 8 bits each for red, green, and blue, plus 5 bits for brightness
5#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
6pub struct Apa102Pixel {
7    pub red: u8,
8    pub green: u8,
9    pub blue: u8,
10    pub brightness: u5,
11}
12
13#[cfg(feature = "defmt")]
14impl defmt::Format for Apa102Pixel {
15    fn format(&self, fmt: defmt::Formatter) {
16        defmt::write!(
17            fmt,
18            "Apa102Pixel {{ red: {=u8:?}, green: {=u8:?}, blue: {=u8:?}, brightness: {=u8:?} }}",
19            self.red,
20            self.green,
21            self.blue,
22            u8::from(self.brightness)
23        );
24    }
25}
26
27impl From<RGB8> for Apa102Pixel {
28    /// RGB values are copied as-is and brightness is set to the maximum value (31).
29    fn from(old: RGB8) -> Self {
30        Self {
31            red: old.r,
32            green: old.g,
33            blue: old.b,
34            brightness: u5::MAX,
35        }
36    }
37}
38
39impl Apa102Pixel {
40    /// Convert an [RGB8] to an [Apa102Pixel] with a specified brightness level.
41    /// Any [u8] is a valid brightness level from 0 to 255.
42    /// [FastLED's psuedo-13-bit gamma correction algorithm](https://github.com/FastLED/FastLED/blob/master/APA102.md)
43    /// is used to make use of the dynamic range available from the APA102 protocol, preserving
44    /// color detail at low brightness. In short, it converts:
45    ///
46    /// RGB8 + 8-bit brightness → RGB16 + 5-bit gamma → RGB8 + 5-bit gamma
47    ///
48    /// Optional color correction can be applied between the gamma correction and bitshifting steps.
49    pub fn from_rgb8_with_brightness(
50        rgb8: RGB8,
51        brightness: u8,
52        color_correction: Option<&RGB8>,
53    ) -> Self {
54        crate::pseudo13::five_bit_hd_gamma_bitshift(&rgb8, brightness, color_correction)
55    }
56
57    /// Convert an [RGB16] to an [Apa102Pixel] with a specified brightness level.
58    /// Any [u8] is a valid brightness level from 0 to 255.
59    /// [FastLED's psuedo-13-bit gamma correction algorithm](https://github.com/FastLED/FastLED/blob/master/APA102.md)
60    /// is used to make use of the dynamic range available from the APA102 protocol, preserving
61    /// color detail at low brightness.
62    ///
63    /// This function does not apply gamma correction; the [RGB16] input is assumed to be gamma corrected already.
64    pub fn from_rgb16_with_brightness(rgb16: RGB16, brightness: u8) -> Self {
65        crate::pseudo13::five_bit_bitshift(rgb16, brightness)
66    }
67}