rpi_led_panel/
init_sequence.rs

1use std::{error::Error, str::FromStr};
2
3use crate::{gpio::Gpio, gpio_bits, RGBMatrixConfig};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6pub enum PanelType {
7    FM6126,
8    FM6127,
9}
10
11impl FromStr for PanelType {
12    type Err = Box<dyn Error>;
13
14    fn from_str(s: &str) -> Result<Self, Self::Err> {
15        match s.to_uppercase().as_str() {
16            "FM6126" => Ok(Self::FM6126),
17            "FM6127" => Ok(Self::FM6127),
18            _ => Err(format!("'{s}' is not a valid panel type.").into()),
19        }
20    }
21}
22
23impl PanelType {
24    pub(crate) fn run_init_sequence(self, gpio: &mut Gpio, config: &RGBMatrixConfig) {
25        match self {
26            Self::FM6126 => Self::init_fm6126(gpio, config),
27            Self::FM6127 => Self::init_fm6127(gpio, config),
28        }
29    }
30
31    fn init_fm6126(gpio: &mut Gpio, config: &RGBMatrixConfig) {
32        let hm = &config.hardware_mapping;
33        let columns = config.cols;
34        let bits_on = hm.panels.used_bits() | hm.a;
35        let bits_off = hm.a;
36        let mask = bits_on | hm.strobe;
37
38        let init_b12 = 0b0111_1111_1111_1111; // full bright
39        let init_b13 = 0b0000_0000_0100_0000; // panel on
40
41        gpio.clear_bits(hm.clock | hm.strobe);
42
43        (0..columns).for_each(|c| {
44            let mut value = if init_b12 & (gpio_bits!(c % 16)) == 0 {
45                bits_off
46            } else {
47                bits_on
48            };
49            if c > columns - 12 {
50                value |= hm.strobe;
51            };
52            gpio.write_masked_bits(value, mask);
53            gpio.set_bits(hm.clock);
54            gpio.clear_bits(hm.clock);
55        });
56        gpio.clear_bits(hm.strobe);
57
58        (0..columns).for_each(|c| {
59            let mut value = if init_b13 & (gpio_bits!(c % 16)) == 0 {
60                bits_off
61            } else {
62                bits_on
63            };
64            if c > columns - 13 {
65                value |= hm.strobe;
66            };
67            gpio.write_masked_bits(value, mask);
68            gpio.set_bits(hm.clock);
69            gpio.clear_bits(hm.clock);
70        });
71        gpio.clear_bits(hm.strobe);
72    }
73
74    /// The FM6217 is very similar to the FM6216. FM6217 adds Register 3 to allow for automatic bad pixel
75    /// suppression.
76    fn init_fm6127(gpio: &mut Gpio, config: &RGBMatrixConfig) {
77        let hm = &config.hardware_mapping;
78        let columns = config.cols;
79        let bits_on = hm.panels.color_bits[0].used_bits() | hm.a;
80        let bits_off = 0;
81        let mask = bits_on | hm.strobe;
82
83        let init_b12 = 0b1111_1111_1100_1110; // register 1
84        let init_b13 = 0b1110_0000_0110_0010; // register 2.
85        let init_b11 = 0b0101_1111_0000_0000; // register 3.
86
87        gpio.clear_bits(hm.clock | hm.strobe);
88
89        (0..columns).for_each(|c| {
90            let mut value = if init_b12 & (gpio_bits!(c % 16)) == 0 {
91                bits_off
92            } else {
93                bits_on
94            };
95            if c > columns - 12 {
96                value |= hm.strobe;
97            };
98            gpio.write_masked_bits(value, mask);
99            gpio.set_bits(hm.clock);
100            gpio.clear_bits(hm.clock);
101        });
102        gpio.clear_bits(hm.strobe);
103
104        (0..columns).for_each(|c| {
105            let mut value = if init_b13 & (gpio_bits!(c % 16)) == 0 {
106                bits_off
107            } else {
108                bits_on
109            };
110            if c > columns - 13 {
111                value |= hm.strobe;
112            };
113            gpio.write_masked_bits(value, mask);
114            gpio.set_bits(hm.clock);
115            gpio.clear_bits(hm.clock);
116        });
117        gpio.clear_bits(hm.strobe);
118
119        (0..columns).for_each(|c| {
120            let mut value = if init_b11 & (gpio_bits!(c % 16)) == 0 {
121                bits_off
122            } else {
123                bits_on
124            };
125            if c > columns - 11 {
126                value |= hm.strobe;
127            };
128            gpio.write_masked_bits(value, mask);
129            gpio.set_bits(hm.clock);
130            gpio.clear_bits(hm.clock);
131        });
132        gpio.clear_bits(hm.strobe);
133    }
134}