1use capsules_core::virtualizers::virtual_i2c::{I2CDevice, MuxI2C};
28use capsules_core::virtualizers::virtual_spi::MuxSpiMaster;
29use capsules_core::virtualizers::virtual_spi::VirtualSpiMasterDevice;
30use capsules_extra::bus::{Bus8080Bus, I2CMasterBus, SpiMasterBus};
31use core::mem::MaybeUninit;
32use kernel::component::Component;
33use kernel::hil::bus8080;
34use kernel::hil::i2c;
35use kernel::hil::spi::{self, ClockPhase, ClockPolarity, SpiMasterDevice};
36
37#[macro_export]
39macro_rules! bus8080_bus_component_static {
40 ($B:ty $(,)?) => {{
41 kernel::static_buf!(capsules_extra::bus::Bus8080Bus<'static, $B>)
42 };};
43}
44
45#[macro_export]
46macro_rules! spi_bus_component_static {
47 ($S:ty $(,)?) => {{
48 let spi = kernel::static_buf!(
49 capsules_core::virtualizers::virtual_spi::VirtualSpiMasterDevice<'static, $S>
50 );
51 let address_buffer = kernel::static_buf!([u8; core::mem::size_of::<usize>()]);
52 let bus = kernel::static_buf!(
53 capsules_extra::bus::SpiMasterBus<
54 'static,
55 capsules_core::virtualizers::virtual_spi::VirtualSpiMasterDevice<'static, $S>,
56 >
57 );
58
59 (spi, bus, address_buffer)
60 };};
61}
62
63#[macro_export]
64macro_rules! i2c_master_bus_component_static {
65 ($D:ty $(,)?) => {{
66 let address_buffer = kernel::static_buf!([u8; 1]);
67 let bus = kernel::static_buf!(capsules_extra::bus::I2CMasterBus<'static, $D>);
68 let i2c_device = kernel::static_buf!(
69 capsules_core::virtualizers::virtual_i2c::I2CDevice<
70 'static,
71 capsules_extra::bus::I2CMasterBus<'static, $D>,
72 >
73 );
74
75 (bus, i2c_device, address_buffer)
76 };};
77}
78
79pub struct Bus8080BusComponent<B: 'static + bus8080::Bus8080<'static>> {
80 bus: &'static B,
81}
82
83impl<B: 'static + bus8080::Bus8080<'static>> Bus8080BusComponent<B> {
84 pub fn new(bus: &'static B) -> Bus8080BusComponent<B> {
85 Bus8080BusComponent { bus }
86 }
87}
88
89impl<B: 'static + bus8080::Bus8080<'static>> Component for Bus8080BusComponent<B> {
90 type StaticInput = &'static mut MaybeUninit<Bus8080Bus<'static, B>>;
91 type Output = &'static Bus8080Bus<'static, B>;
92
93 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
94 let bus = static_buffer.write(Bus8080Bus::new(self.bus));
95 self.bus.set_client(bus);
96
97 bus
98 }
99}
100
101pub struct SpiMasterBusComponent<S: 'static + spi::SpiMaster<'static>> {
102 spi_mux: &'static MuxSpiMaster<'static, S>,
103 chip_select: S::ChipSelect,
104 baud_rate: u32,
105 clock_phase: ClockPhase,
106 clock_polarity: ClockPolarity,
107}
108
109impl<S: 'static + spi::SpiMaster<'static>> SpiMasterBusComponent<S> {
110 pub fn new(
111 spi_mux: &'static MuxSpiMaster<'static, S>,
112 chip_select: S::ChipSelect,
113 baud_rate: u32,
114 clock_phase: ClockPhase,
115 clock_polarity: ClockPolarity,
116 ) -> SpiMasterBusComponent<S> {
117 SpiMasterBusComponent {
118 spi_mux,
119 chip_select,
120 baud_rate,
121 clock_phase,
122 clock_polarity,
123 }
124 }
125}
126
127impl<S: 'static + spi::SpiMaster<'static>> Component for SpiMasterBusComponent<S> {
128 type StaticInput = (
129 &'static mut MaybeUninit<VirtualSpiMasterDevice<'static, S>>,
130 &'static mut MaybeUninit<SpiMasterBus<'static, VirtualSpiMasterDevice<'static, S>>>,
131 &'static mut MaybeUninit<[u8; core::mem::size_of::<usize>()]>,
132 );
133 type Output = &'static SpiMasterBus<'static, VirtualSpiMasterDevice<'static, S>>;
134
135 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
136 let spi_device = static_buffer
137 .0
138 .write(VirtualSpiMasterDevice::new(self.spi_mux, self.chip_select));
139 spi_device.setup();
140
141 if let Err(error) =
142 spi_device.configure(self.clock_polarity, self.clock_phase, self.baud_rate)
143 {
144 panic!("Failed to setup SPI Bus ({:?})", error);
145 }
146
147 let buffer = static_buffer.2.write([0; core::mem::size_of::<usize>()]);
148
149 let bus = static_buffer.1.write(SpiMasterBus::new(spi_device, buffer));
150 spi_device.set_client(bus);
151
152 bus
153 }
154}
155
156pub struct I2CMasterBusComponent<I: 'static + i2c::I2CMaster<'static>> {
157 i2c_mux: &'static MuxI2C<'static, I>,
158 address: u8,
159}
160
161impl<I: 'static + i2c::I2CMaster<'static>> I2CMasterBusComponent<I> {
162 pub fn new(i2c_mux: &'static MuxI2C<'static, I>, address: u8) -> I2CMasterBusComponent<I> {
163 I2CMasterBusComponent { i2c_mux, address }
164 }
165}
166
167impl<I: 'static + i2c::I2CMaster<'static>> Component for I2CMasterBusComponent<I> {
168 type StaticInput = (
169 &'static mut MaybeUninit<I2CMasterBus<'static, I2CDevice<'static, I>>>,
170 &'static mut MaybeUninit<I2CDevice<'static, I>>,
171 &'static mut MaybeUninit<[u8; 1]>,
172 );
173 type Output = &'static I2CMasterBus<'static, I2CDevice<'static, I>>;
174
175 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
176 let i2c_device = static_buffer
177 .1
178 .write(I2CDevice::new(self.i2c_mux, self.address));
179 let buffer = static_buffer.2.write([0; 1]);
180
181 let bus = static_buffer.0.write(I2CMasterBus::new(i2c_device, buffer));
182 i2c_device.set_client(bus);
183
184 bus
185 }
186}