1use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
42use capsules_extra::bus::{self, BusAddr8};
43use capsules_extra::st77xx::{ST77XXScreen, ST77XX};
44use core::mem::MaybeUninit;
45use kernel::component::Component;
46use kernel::hil::gpio;
47use kernel::hil::time::{self, Alarm};
48
49#[macro_export]
51macro_rules! st77xx_component_static {
52 ($B: ty, $A:ty, $P:ty $(,)?) => {{
53 let buffer = kernel::static_buf!([u8; capsules_extra::st77xx::BUFFER_SIZE]);
54 let sequence_buffer = kernel::static_buf!(
55 [capsules_extra::st77xx::SendCommand; capsules_extra::st77xx::SEQUENCE_BUFFER_SIZE]
56 );
57 let st77xx_alarm = kernel::static_buf!(
58 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>
59 );
60 let st77xx = kernel::static_buf!(
61 capsules_extra::st77xx::ST77XX<
62 'static,
63 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>,
64 $B,
65 $P,
66 >
67 );
68
69 (st77xx_alarm, st77xx, buffer, sequence_buffer)
70 };};
71}
72
73pub struct ST77XXComponent<
74 A: 'static + time::Alarm<'static>,
75 B: 'static + bus::Bus<'static, BusAddr8>,
76 P: 'static + gpio::Pin,
77> {
78 alarm_mux: &'static MuxAlarm<'static, A>,
79 bus: &'static B,
80 dc: Option<&'static P>,
81 reset: Option<&'static P>,
82 screen: &'static ST77XXScreen,
83}
84
85impl<
86 A: 'static + time::Alarm<'static>,
87 B: 'static + bus::Bus<'static, BusAddr8>,
88 P: 'static + gpio::Pin,
89 > ST77XXComponent<A, B, P>
90{
91 pub fn new(
92 alarm_mux: &'static MuxAlarm<'static, A>,
93 bus: &'static B,
94 dc: Option<&'static P>,
95 reset: Option<&'static P>,
96 screen: &'static ST77XXScreen,
97 ) -> ST77XXComponent<A, B, P> {
98 ST77XXComponent {
99 alarm_mux,
100 bus,
101 dc,
102 reset,
103 screen,
104 }
105 }
106}
107
108impl<
109 A: 'static + time::Alarm<'static>,
110 B: 'static + bus::Bus<'static, BusAddr8>,
111 P: 'static + gpio::Pin,
112 > Component for ST77XXComponent<A, B, P>
113{
114 type StaticInput = (
115 &'static mut MaybeUninit<VirtualMuxAlarm<'static, A>>,
116 &'static mut MaybeUninit<ST77XX<'static, VirtualMuxAlarm<'static, A>, B, P>>,
117 &'static mut MaybeUninit<[u8; capsules_extra::st77xx::BUFFER_SIZE]>,
118 &'static mut MaybeUninit<
119 [capsules_extra::st77xx::SendCommand; capsules_extra::st77xx::SEQUENCE_BUFFER_SIZE],
120 >,
121 );
122 type Output = &'static ST77XX<'static, VirtualMuxAlarm<'static, A>, B, P>;
123
124 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
125 let st77xx_alarm = static_buffer.0.write(VirtualMuxAlarm::new(self.alarm_mux));
126 st77xx_alarm.setup();
127
128 let buffer = static_buffer
129 .2
130 .write([0; capsules_extra::st77xx::BUFFER_SIZE]);
131 let sequence_buffer = static_buffer.3.write(
132 [capsules_extra::st77xx::SendCommand::Nop;
133 capsules_extra::st77xx::SEQUENCE_BUFFER_SIZE],
134 );
135
136 let st77xx = static_buffer.1.write(ST77XX::new(
137 self.bus,
138 st77xx_alarm,
139 self.dc,
140 self.reset,
141 buffer,
142 sequence_buffer,
143 self.screen,
144 ));
145 self.bus.set_client(st77xx);
146 st77xx_alarm.set_alarm_client(st77xx);
147
148 st77xx
149 }
150}