components/
lsm303agr.rs
1use capsules_core::virtualizers::virtual_i2c::{I2CDevice, MuxI2C};
27use capsules_extra::lsm303agr::Lsm303agrI2C;
28use capsules_extra::lsm303xx;
29use core::mem::MaybeUninit;
30use kernel::capabilities;
31use kernel::component::Component;
32use kernel::create_capability;
33use kernel::hil::i2c;
34
35#[macro_export]
37macro_rules! lsm303agr_component_static {
38 ($I:ty $(,)?) => {{
39 let buffer = kernel::static_buf!([u8; 8]);
40 let accelerometer_i2c =
41 kernel::static_buf!(capsules_core::virtualizers::virtual_i2c::I2CDevice<$I>);
42 let magnetometer_i2c =
43 kernel::static_buf!(capsules_core::virtualizers::virtual_i2c::I2CDevice<$I>);
44 let lsm303agr = kernel::static_buf!(
45 capsules_extra::lsm303agr::Lsm303agrI2C<
46 'static,
47 capsules_core::virtualizers::virtual_i2c::I2CDevice<$I>,
48 >
49 );
50
51 (accelerometer_i2c, magnetometer_i2c, buffer, lsm303agr)
52 };};
53}
54
55pub struct Lsm303agrI2CComponent<I: 'static + i2c::I2CMaster<'static>> {
56 i2c_mux: &'static MuxI2C<'static, I>,
57 accelerometer_i2c_address: u8,
58 magnetometer_i2c_address: u8,
59 board_kernel: &'static kernel::Kernel,
60 driver_num: usize,
61}
62
63impl<I: 'static + i2c::I2CMaster<'static>> Lsm303agrI2CComponent<I> {
64 pub fn new(
65 i2c_mux: &'static MuxI2C<'static, I>,
66 accelerometer_i2c_address: Option<u8>,
67 magnetometer_i2c_address: Option<u8>,
68 board_kernel: &'static kernel::Kernel,
69 driver_num: usize,
70 ) -> Lsm303agrI2CComponent<I> {
71 Lsm303agrI2CComponent {
72 i2c_mux,
73 accelerometer_i2c_address: accelerometer_i2c_address
74 .unwrap_or(lsm303xx::ACCELEROMETER_BASE_ADDRESS),
75 magnetometer_i2c_address: magnetometer_i2c_address
76 .unwrap_or(lsm303xx::MAGNETOMETER_BASE_ADDRESS),
77 board_kernel,
78 driver_num,
79 }
80 }
81}
82
83impl<I: 'static + i2c::I2CMaster<'static>> Component for Lsm303agrI2CComponent<I> {
84 type StaticInput = (
85 &'static mut MaybeUninit<I2CDevice<'static, I>>,
86 &'static mut MaybeUninit<I2CDevice<'static, I>>,
87 &'static mut MaybeUninit<[u8; 8]>,
88 &'static mut MaybeUninit<Lsm303agrI2C<'static, I2CDevice<'static, I>>>,
89 );
90 type Output = &'static Lsm303agrI2C<'static, I2CDevice<'static, I>>;
91
92 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
93 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
94
95 let buffer = static_buffer.2.write([0; 8]);
96
97 let accelerometer_i2c = static_buffer
98 .0
99 .write(I2CDevice::new(self.i2c_mux, self.accelerometer_i2c_address));
100 let magnetometer_i2c = static_buffer
101 .1
102 .write(I2CDevice::new(self.i2c_mux, self.magnetometer_i2c_address));
103
104 let grant = self.board_kernel.create_grant(self.driver_num, &grant_cap);
105 let lsm303agr = static_buffer.3.write(Lsm303agrI2C::new(
106 accelerometer_i2c,
107 magnetometer_i2c,
108 buffer,
109 grant,
110 ));
111 accelerometer_i2c.set_client(lsm303agr);
112 magnetometer_i2c.set_client(lsm303agr);
113
114 lsm303agr
115 }
116}