components/
bmp280.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 BMP280 Temperature and Pressure Sensor.
6//!
7//! Based off the SHT3x code.
8//!
9//! I2C Interface
10//!
11//! Usage
12//! -----
13//!
14//! With the default i2c address
15//! ```rust
16//! let bmp280 = components::bmp280::Bmp280Component::new(sensors_i2c_bus, mux_alarm).finalize(
17//!         components::bmp280_component_static!(nrf52::rtc::Rtc<'static>),
18//!     );
19//! bmp280.begin_reset();
20//! ```
21//!
22//! With a specified i2c address
23//! ```rust
24//! let bmp280 = components::bmp280::Bmp280Component::new(sensors_i2c_bus, mux_alarm).finalize(
25//!         components::bmp280_component_static!(nrf52::rtc::Rtc<'static>, capsules_extra::bmp280::BASE_ADDR),
26//!     );
27//! bmp280.begin_reset();
28//! ```
29
30use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
31use capsules_core::virtualizers::virtual_i2c::{I2CDevice, MuxI2C};
32use capsules_extra::bmp280::Bmp280;
33use core::mem::MaybeUninit;
34use kernel::component::Component;
35use kernel::hil::i2c;
36use kernel::hil::time::Alarm;
37
38#[macro_export]
39macro_rules! bmp280_component_static {
40    ($A:ty, $I:ty $(,)?) => {{
41        let i2c_device =
42            kernel::static_buf!(capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, $I>);
43        let alarm = kernel::static_buf!(
44            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>
45        );
46        let buffer = kernel::static_buf!([u8; capsules_extra::bmp280::BUFFER_SIZE]);
47        let bmp280 = kernel::static_buf!(
48            capsules_extra::bmp280::Bmp280<
49                'static,
50                VirtualMuxAlarm<'static, $A>,
51                capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, $I>,
52            >
53        );
54
55        (i2c_device, alarm, buffer, bmp280)
56    };};
57}
58
59pub type Bmp280ComponentType<A, I> = capsules_extra::bmp280::Bmp280<'static, A, I>;
60
61pub struct Bmp280Component<A: 'static + Alarm<'static>, I: 'static + i2c::I2CMaster<'static>> {
62    i2c_mux: &'static MuxI2C<'static, I>,
63    i2c_address: u8,
64    alarm_mux: &'static MuxAlarm<'static, A>,
65}
66
67impl<A: 'static + Alarm<'static>, I: 'static + i2c::I2CMaster<'static>> Bmp280Component<A, I> {
68    pub fn new(
69        i2c_mux: &'static MuxI2C<'static, I>,
70        i2c_address: u8,
71        alarm_mux: &'static MuxAlarm<'static, A>,
72    ) -> Bmp280Component<A, I> {
73        Bmp280Component {
74            i2c_mux,
75            i2c_address,
76            alarm_mux,
77        }
78    }
79}
80
81impl<A: 'static + Alarm<'static>, I: 'static + i2c::I2CMaster<'static>> Component
82    for Bmp280Component<A, I>
83{
84    type StaticInput = (
85        &'static mut MaybeUninit<I2CDevice<'static, I>>,
86        &'static mut MaybeUninit<VirtualMuxAlarm<'static, A>>,
87        &'static mut MaybeUninit<[u8; capsules_extra::bmp280::BUFFER_SIZE]>,
88        &'static mut MaybeUninit<
89            Bmp280<'static, VirtualMuxAlarm<'static, A>, I2CDevice<'static, I>>,
90        >,
91    );
92    type Output = &'static Bmp280<'static, VirtualMuxAlarm<'static, A>, I2CDevice<'static, I>>;
93
94    fn finalize(self, s: Self::StaticInput) -> Self::Output {
95        let bmp280_i2c = s.0.write(I2CDevice::new(self.i2c_mux, self.i2c_address));
96        let bmp280_alarm = s.1.write(VirtualMuxAlarm::new(self.alarm_mux));
97        bmp280_alarm.setup();
98
99        let buffer = s.2.write([0; capsules_extra::bmp280::BUFFER_SIZE]);
100
101        let bmp280 = s.3.write(Bmp280::new(bmp280_i2c, buffer, bmp280_alarm));
102        bmp280_i2c.set_client(bmp280);
103        bmp280_alarm.set_alarm_client(bmp280);
104
105        bmp280
106    }
107}