components/
lsm6dsox.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Component for the LSM6DSOXTR Sensor
6//!
7//! Usage
8//! ------
9//!
10//! ```rust
11//! let lsm6dsoxtr = components::lsm6dsox::Lsm6dsoxtrI2CComponent::new(
12//!     mux_i2c,
13//!     capsules_extra::lsm6dsoxtr::ACCELEROMETER_BASE_ADDRESS,
14//!     board_kernel,
15//!     capsules_extra::lsm6dsoxtr::DRIVER_NUM,
16//! )
17//! .finalize(components::lsm6ds_i2c_component_static!());
18//!
19//! let _ = lsm6dsoxtr
20//!          .configure(
21//!              capsules_extra::lsm6ds_definitions::LSM6DSOXGyroDataRate::LSM6DSOX_GYRO_RATE_12_5_HZ,
22//!              capsules_extra::lsm6ds_definitions::LSM6DSOXAccelDataRate::LSM6DSOX_ACCEL_RATE_12_5_HZ,
23//!              capsules_extra::lsm6ds_definitions::LSM6DSOXAccelRange::LSM6DSOX_ACCEL_RANGE_2_G,
24//!              capsules_extra::lsm6ds_definitions::LSM6DSOXTRGyroRange::LSM6DSOX_GYRO_RANGE_250_DPS,
25//!              true,
26//!          )
27//!          .map_err(|e| panic!("ERROR Failed LSM6DSOXTR sensor configuration ({:?})", e));
28//! ```
29//! Author: Cristiana Andrei <cristiana.andrei@stud.fils.upb.ro>
30
31use capsules_core::virtualizers::virtual_i2c::{I2CDevice, MuxI2C};
32use capsules_extra::lsm6dsoxtr::Lsm6dsoxtrI2C;
33use core::mem::MaybeUninit;
34use kernel::capabilities;
35use kernel::component::Component;
36use kernel::create_capability;
37use kernel::hil::i2c;
38
39// Setup static space for the objects.
40#[macro_export]
41macro_rules! lsm6ds_i2c_component_static {
42    ($I:ty $(,)?) => {{
43        let buffer = kernel::static_buf!([u8; 8]);
44        let i2c_device =
45            kernel::static_buf!(capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, $I>);
46        let lsm6dsoxtr = kernel::static_buf!(
47            capsules_extra::lsm6dsoxtr::Lsm6dsoxtrI2C<
48                'static,
49                capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, $I>,
50            >
51        );
52
53        (i2c_device, buffer, lsm6dsoxtr)
54    };};
55}
56
57pub struct Lsm6dsoxtrI2CComponent<I: 'static + i2c::I2CMaster<'static>> {
58    i2c_mux: &'static MuxI2C<'static, I>,
59    i2c_address: u8,
60    board_kernel: &'static kernel::Kernel,
61    driver_num: usize,
62}
63
64impl<I: 'static + i2c::I2CMaster<'static>> Lsm6dsoxtrI2CComponent<I> {
65    pub fn new(
66        i2c_mux: &'static MuxI2C<'static, I>,
67        i2c_address: u8,
68        board_kernel: &'static kernel::Kernel,
69        driver_num: usize,
70    ) -> Lsm6dsoxtrI2CComponent<I> {
71        Lsm6dsoxtrI2CComponent {
72            i2c_mux,
73            i2c_address,
74            board_kernel,
75            driver_num,
76        }
77    }
78}
79
80impl<I: 'static + i2c::I2CMaster<'static>> Component for Lsm6dsoxtrI2CComponent<I> {
81    type StaticInput = (
82        &'static mut MaybeUninit<I2CDevice<'static, I>>,
83        &'static mut MaybeUninit<[u8; 8]>,
84        &'static mut MaybeUninit<Lsm6dsoxtrI2C<'static, I2CDevice<'static, I>>>,
85    );
86    type Output = &'static Lsm6dsoxtrI2C<'static, I2CDevice<'static, I>>;
87
88    fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
89        let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
90        let grant = self.board_kernel.create_grant(self.driver_num, &grant_cap);
91
92        let lsm6dsox_i2c = static_buffer
93            .0
94            .write(I2CDevice::new(self.i2c_mux, self.i2c_address));
95        let buffer = static_buffer.1.write([0; 8]);
96
97        let lsm6dsox = static_buffer
98            .2
99            .write(Lsm6dsoxtrI2C::new(lsm6dsox_i2c, buffer, grant));
100        lsm6dsox_i2c.set_client(lsm6dsox);
101
102        lsm6dsox
103    }
104}