components/
chirp_i2c_moisture.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//! Components for the Chirp I2C Moisture Sensor.
6//! <https://www.tindie.com/products/miceuz/i2c-soil-moisture-sensor/>
7//!
8//! Usage
9//! -----
10//! ```rust
11//!    let chirp_moisture =
12//!        components::chirp_i2c_moisture::ChirpI2cMoistureComponent::new(mux_i2c, 0x20).finalize(
13//!            components::chirp_i2c_moisture_component_static!(apollo3::iom::Iom<'static>),
14//!        );
15//!
16//!    let moisture = components::moisture::MoistureComponent::new(
17//!        board_kernel,
18//!        capsules_extra::moisture::DRIVER_NUM,
19//!        chirp_moisture,
20//!    )
21//!    .finalize(components::moisture_component_static!(ChirpI2cMoistureType));
22//! ```
23
24use capsules_core::virtualizers::virtual_i2c::{I2CDevice, MuxI2C};
25use capsules_extra::chirp_i2c_moisture::{ChirpI2cMoisture, BUFFER_SIZE};
26use core::mem::MaybeUninit;
27use kernel::component::Component;
28use kernel::hil::i2c;
29
30// Setup static space for the objects.
31#[macro_export]
32macro_rules! chirp_i2c_moisture_component_static {
33    ($I:ty $(,)?) => {{
34        let i2c_device =
35            kernel::static_buf!(capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, $I>);
36        let i2c_buffer = kernel::static_buf!([u8; capsules_extra::chirp_i2c_moisture::BUFFER_SIZE]);
37        let chirp_i2c_moisture = kernel::static_buf!(
38            capsules_extra::chirp_i2c_moisture::ChirpI2cMoisture<
39                'static,
40                capsules_core::virtualizers::virtual_i2c::I2CDevice<$I>,
41            >
42        );
43
44        (i2c_device, i2c_buffer, chirp_i2c_moisture)
45    };};
46}
47
48pub type ChirpI2cMoistureComponentType<I> =
49    capsules_extra::chirp_i2c_moisture::ChirpI2cMoisture<'static, I>;
50
51pub struct ChirpI2cMoistureComponent<I: 'static + i2c::I2CMaster<'static>> {
52    i2c_mux: &'static MuxI2C<'static, I>,
53    i2c_address: u8,
54}
55
56impl<I: 'static + i2c::I2CMaster<'static>> ChirpI2cMoistureComponent<I> {
57    pub fn new(i2c: &'static MuxI2C<'static, I>, i2c_address: u8) -> Self {
58        ChirpI2cMoistureComponent {
59            i2c_mux: i2c,
60            i2c_address,
61        }
62    }
63}
64
65impl<I: 'static + i2c::I2CMaster<'static>> Component for ChirpI2cMoistureComponent<I> {
66    type StaticInput = (
67        &'static mut MaybeUninit<I2CDevice<'static, I>>,
68        &'static mut MaybeUninit<[u8; BUFFER_SIZE]>,
69        &'static mut MaybeUninit<ChirpI2cMoisture<'static, I2CDevice<'static, I>>>,
70    );
71    type Output = &'static ChirpI2cMoisture<'static, I2CDevice<'static, I>>;
72
73    fn finalize(self, s: Self::StaticInput) -> Self::Output {
74        let chirp_i2c_moisture_i2c = s.0.write(I2CDevice::new(self.i2c_mux, self.i2c_address));
75        let i2c_buffer = s.1.write([0; BUFFER_SIZE]);
76
77        let chirp_i2c_moisture =
78            s.2.write(ChirpI2cMoisture::new(chirp_i2c_moisture_i2c, i2c_buffer));
79
80        chirp_i2c_moisture_i2c.set_client(chirp_i2c_moisture);
81        chirp_i2c_moisture
82    }
83}