1use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
73use capsules_extra::led_matrix::LedMatrixDriver;
74use core::mem::MaybeUninit;
75use kernel::component::Component;
76use kernel::hil::gpio::{ActivationMode, Pin};
77use kernel::hil::time::Alarm;
78
79#[macro_export]
80macro_rules! led_matrix_component_static {
81 ($Pin:ty, $A: ty, $num_cols: literal, $num_rows: literal $(,)?) => {{
82 let buffer = kernel::static_buf!([u8; $num_cols * $num_rows / 8 + 1]);
83 let alarm = kernel::static_buf!(
84 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>
85 );
86 let led = kernel::static_buf!(
87 capsules_extra::led_matrix::LedMatrixDriver<
88 'static,
89 $Pin,
90 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>,
91 >
92 );
93
94 (alarm, led, buffer)
95 };};
96}
97
98#[macro_export]
99macro_rules! led_line_component_static {
100 ($Pin:ty, $($L:expr),+ $(,)?) => {{
101 use kernel::count_expressions;
102 use kernel::static_init;
103 const NUM_LEDS: usize = count_expressions!($($L),+);
104
105 static_init!(
106 [&'static $Pin; NUM_LEDS],
107 [
108 $(
109 static_init!(
110 &'static $Pin,
111 $L
112 )
113 ),+
114 ]
115 )
116 };};
117}
118
119#[macro_export]
120macro_rules! led_matrix_led {
121 ($Pin:ty, $A: ty, $led_matrix: expr, $col: expr, $row: expr) => {{
122 use capsules_extra::led_matrix::LedMatrixLed;
123 static_init!(
124 LedMatrixLed<'static, $Pin, $A>,
125 LedMatrixLed::new($led_matrix, $col, $row)
126 )
127 };};
128}
129
130#[macro_export]
131macro_rules! led_matrix_leds {
132 ($Pin:ty, $A: ty, $led_matrix: expr, $(($col: expr, $row: expr)),+) => {{
133 use capsules_extra::led_matrix::LedMatrixLed;
134 use kernel::count_expressions;
135
136 const NUM_LEDS: usize = count_expressions!($(($col, $row)),+);
137 let leds = static_init!(
138 [&LedMatrixLed<'static, $Pin, $A>; NUM_LEDS],
139 [$(
140 $crate::led_matrix_led! ($Pin, $A, $led_matrix, $col, $row)
141 ),+]
142 );
143 leds
144 };};
145}
146
147pub struct LedMatrixComponent<
148 L: 'static + Pin,
149 A: 'static + Alarm<'static>,
150 const NUM_COLS: usize,
151 const NUM_ROWS: usize,
152 const NUM_LED_BITS: usize,
153> {
154 alarm_mux: &'static MuxAlarm<'static, A>,
155 col: &'static [&'static L; NUM_COLS],
156 row: &'static [&'static L; NUM_ROWS],
157 col_active: ActivationMode,
158 row_active: ActivationMode,
159 refresh_rate: usize,
160}
161
162impl<
163 L: 'static + Pin,
164 A: 'static + Alarm<'static>,
165 const NUM_COLS: usize,
166 const NUM_ROWS: usize,
167 const NUM_LED_BITS: usize,
168 > LedMatrixComponent<L, A, NUM_COLS, NUM_ROWS, NUM_LED_BITS>
169{
170 pub fn new(
171 alarm_mux: &'static MuxAlarm<'static, A>,
172 col: &'static [&'static L; NUM_COLS],
173 row: &'static [&'static L; NUM_ROWS],
174 col_active: ActivationMode,
175 row_active: ActivationMode,
176 refresh_rate: usize,
177 ) -> Self {
178 Self {
179 alarm_mux,
180 col,
181 row,
182 col_active,
183 row_active,
184 refresh_rate,
185 }
186 }
187}
188
189impl<
190 L: 'static + Pin,
191 A: 'static + Alarm<'static>,
192 const NUM_COLS: usize,
193 const NUM_ROWS: usize,
194 const NUM_LED_BITS: usize,
195 > Component for LedMatrixComponent<L, A, NUM_COLS, NUM_ROWS, NUM_LED_BITS>
196{
197 type StaticInput = (
198 &'static mut MaybeUninit<VirtualMuxAlarm<'static, A>>,
199 &'static mut MaybeUninit<LedMatrixDriver<'static, L, VirtualMuxAlarm<'static, A>>>,
200 &'static mut MaybeUninit<[u8; NUM_LED_BITS]>,
201 );
202 type Output = &'static LedMatrixDriver<'static, L, VirtualMuxAlarm<'static, A>>;
203
204 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
205 let led_alarm = static_buffer.0.write(VirtualMuxAlarm::new(self.alarm_mux));
206 led_alarm.setup();
207
208 let buffer = static_buffer.2.write([0; NUM_LED_BITS]);
209
210 let led_matrix = static_buffer.1.write(LedMatrixDriver::new(
211 self.col,
212 self.row,
213 buffer,
214 led_alarm,
215 self.col_active,
216 self.row_active,
217 self.refresh_rate,
218 ));
219
220 led_alarm.set_alarm_client(led_matrix);
221
222 led_matrix.init();
223
224 led_matrix
225 }
226}