8000 Soil Moisture Sensor Support by alistair23 · Pull Request #4144 · tock/tock · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Soil Moisture Sensor Support #4144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ ci-job-cargo-test-build:
@$(MAKE) NO_RUN="--no-run" -C "boards/esp32-c3-devkitM-1" test
@$(MAKE) NO_RUN="--no-run" -C "boards/apollo3/lora_things_plus" test
@$(MAKE) NO_RUN="--no-run" -C "boards/apollo3/lora_things_plus" test-atecc508a
@$(MAKE) NO_RUN="--no-run" -C "boards/apollo3/lora_things_plus" test-chirp_i2c_moisture
@$(MAKE) NO_RUN="--no-run" -C "boards/apollo3/redboard_artemis_atp" test
@$(MAKE) NO_RUN="--no-run" -C "boards/apollo3/redboard_artemis_nano" test

Expand Down
8 changes: 8 additions & 0 deletions boards/apollo3/lora_things_plus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,11 @@ default = []
# NOTE: That the first time this is used it will lock the device, which
# can not be undone.
atecc508a = []

# This feature enables support for the Chirp I2C Soil Moisture Sensor.
# This is the sensor avaliable from
# https://www.tindie.com/products/miceuz/i2c-soil-moisture-sensor/
#
# If the sensor is attached via the I2C Qwiic connecter you should
# enable this feature.
chirp_i2c_moisture = []
11 changes: 9 additions & 2 deletions boards/apollo3/lora_things_plus/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,15 @@ flash-app:

.PHONY: test
test:
$(Q)OBJCOPY=${OBJCOPY} PORT=$(PORT) $(CARGO) test $(NO_RUN) --bin $(PLATFORM) --release
$(Q)OBJCOPY=${OBJCOPY} PORT=$(PORT) $(CARGO) test $(NO_RUN) \
--bin $(PLATFORM) --release

.PHONY: test-atecc508a
test-atecc508a:
$(Q)OBJCOPY=${OBJCOPY} PORT=$(PORT) $(CARGO) test $(NO_RUN) --bin $(PLATFORM) --release --features atecc508a
$(Q)OBJCOPY=${OBJCOPY} PORT=$(PORT) $(CARGO) test $(NO_RUN) \
--bin $(PLATFORM) --release --features atecc508a

.PHONY: test-chirp_i2c_moisture
test-chirp_i2c_moisture:
$(Q)OBJCOPY=${OBJCOPY} PORT=$(PORT) $(CARGO) test $(NO_RUN) \
--bin $(PLATFORM) --release --features chirp_i2c_moisture
46 changes: 46 additions & 0 deletions boards/apollo3/lora_things_plus/src/main.rs
6D4E
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ use {
kernel::hil::rng::Rng,
};

#[cfg(feature = "chirp_i2c_moisture")]
use capsules_core::virtualizers::virtual_i2c::MuxI2C;

/// Support routines for debugging I/O.
pub mod io;

Expand Down Expand Up @@ -122,9 +125,13 @@ pub static mut STACK_MEMORY: [u8; 0x1000] = [0; 0x1000];
const LORA_SPI_DRIVER_NUM: usize = capsules_core::driver::NUM::LoRaPhySPI as usize;
const LORA_GPIO_DRIVER_NUM: usize = capsules_core::driver::NUM::LoRaPhyGPIO as usize;

type ChirpI2cMoistureType = components::chirp_i2c_moisture::ChirpI2cMoistureComponentType<
capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, apollo3::iom::Iom<'static>>,
>;
type BME280Sensor = components::bme280::Bme280ComponentType<
capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, apollo3::iom::Iom<'static>>,
>;

type TemperatureDriver = components::temperature::TemperatureComponentType<BME280Sensor>;
type HumidityDriver = components::humidity::HumidityComponentType<BME280Sensor>;

Expand Down Expand Up @@ -167,6 +174,7 @@ struct LoRaThingsPlus {
temperature: &'static TemperatureDriver,
humidity: &'static HumidityDriver,
air_quality: &'static capsules_extra::air_quality::AirQualitySensor<'static>,
moisture: Option<&'static components::moisture::MoistureComponentType<ChirpI2cMoistureType>>,
rng: Option<
&'static capsules_core::rng::RngDriver<
'static,
Expand Down Expand Up @@ -263,6 +271,27 @@ unsafe fn setup_atecc508a(
rng_local
}

#[cfg(feature = "chirp_i2c_moisture")]
unsafe fn setup_chirp_i2c_moisture(
board_kernel: &'static kernel::Kernel,
_memory_allocation_cap: &dyn capabilities::MemoryAllocationCapability,
mux_i2c: &'static MuxI2C<'static, apollo3::iom::Iom<'static>>,
) -> &'static components::moisture::MoistureComponentType<ChirpI2cMoistureType> {
let chirp_moisture =
components::chirp_i2c_moisture::ChirpI2cMoistureComponent::new(mux_i2c, 0x20).finalize(
components::chirp_i2c_moisture_component_static!(apollo3::iom::Iom<'static>),
);

let moisture = components::moisture::MoistureComponent::new(
board_kernel,
capsules_extra::moisture::DRIVER_NUM,
chirp_moisture,
)
.finalize(components::moisture_component_static!(ChirpI2cMoistureType));

moisture
}

/// Mapping of integer syscalls to objects that implement syscalls.
impl SyscallDriverLookup for LoRaThingsPlus {
fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
Expand Down Expand Up @@ -290,6 +319,13 @@ impl SyscallDriverLookup for LoRaThingsPlus {
f(None)
}
}
capsules_extra::moisture::DRIVER_NUM => {
if let Some(moisture) = self.moisture {
f(Some(moisture))
} else {
f(None)
}
}
_ => f(None),
}
}
Expand Down Expand Up @@ -494,6 +530,15 @@ unsafe fn setup() -> (
.finalize(components::air_quality_component_static!());
CCS811 = Some(ccs811);

#[cfg(feature = "chirp_i2c_moisture")]
let moisture = Some(setup_chirp_i2c_moisture(
board_kernel,
&memory_allocation_cap,
mux_i2c,
));
#[cfg(not(feature = "chirp_i2c_moisture"))]
let moisture = None;

#[cfg(feature = "atecc508a")]
let rng = Some(setup_atecc508a(
board_kernel,
Expand Down Expand Up @@ -743,6 +788,7 @@ unsafe fn setup() -> (
temperature,
humidity,
air_quality,
moisture,
rng,
scheduler,
systick,
Expand Down
15 changes: 13 additions & 2 deletions boards/apollo3/lora_things_plus/src/tests/environmental_sensors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use crate::{BME280, CCS811};
use core::cell::Cell;
use kernel::debug;
use kernel::hil::sensors::{
AirQualityClient, AirQualityDriver, HumidityClient, HumidityDriver, TemperatureClient,
TemperatureDriver,
AirQualityClient, AirQualityDriver, HumidityClient, HumidityDriver, MoistureClient,
TemperatureClient, TemperatureDriver,
};
use kernel::ErrorCode;

Expand All @@ -23,6 +23,7 @@ struct SensorTestCallback {
humidity_done: Cell<bool>,
co2_done: Cell<bool>,
tvoc_done: Cell<bool>,
moisture_done: Cell<bool>,
calibration_temp: Cell<Option<i32>>,
calibration_humidity: Cell<Option<u32>>,
}
Expand All @@ -36,6 +37,7 @@ impl<'a> SensorTestCallback {
humidity_done: Cell::new(false),
co2_done: Cell::new(false),
tvoc_done: Cell::new(false),
moisture_done: Cell::new(false),
calibration_temp: Cell::new(None),
calibration_humidity: Cell::new(None),
}
Expand All @@ -46,6 +48,7 @@ impl<'a> SensorTestCallback {
self.humidity_done.set(false);
self.co2_done.set(false);
self.tvoc_done.set(false);
self.moisture_done.set(false);
}
}

Expand All @@ -67,6 +70,14 @@ impl<'a> HumidityClient for SensorTestCallback {
}
}

impl<'a> MoistureClient for SensorTestCallback {
fn callback(&self, value: Result<usize, ErrorCode>) {
self.moisture_done.set(true);

debug!("Moisture: {}%", value.unwrap() as f32 / 100.0);
}
}

impl<'a> AirQualityClient for SensorTestCallback {
fn environment_specified(&self, result: Result<(), ErrorCode>) {
result.unwrap();
Expand Down
3 changes: 2 additions & 1 deletion boards/apollo3/redboard_artemis_atp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@ flash-app:

.PHONY: test
test:
$(Q)OBJCOPY=${OBJCOPY} PORT=$(PORT) $(CARGO) test $(NO_RUN) --bin $(PLATFORM) --release
$(Q)OBJCOPY=${OBJCOPY} PORT=$(PORT) $(CARGO) test $(NO_RUN) \
--bin $(PLATFORM) --release
3 changes: 2 additions & 1 deletion boards/apollo3/redboard_artemis_nano/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@ flash-app:

.PHONY: test
test:
$(Q)OBJCOPY=${OBJCOPY} PORT=$(PORT) $(CARGO) test $(NO_RUN) --bin $(PLATFORM) --release
$(Q)OBJCOPY=${OBJCOPY} PORT=$(PORT) $(CARGO) test $(NO_RUN) \
--bin $(PLATFORM) --release
84 changes: 84 additions & 0 deletions boards/components/src/chirp_i2c_moisture.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Licensed under the Apache License, Version 2.0 or the MIT License.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright Tock Contributors 2022.

//! Components for the Chirp I2C Moisture Sensor.
//! <https://www.tindie.com/products/miceuz/i2c-soil-moisture-sensor/>
//!
//! Usage
//! -----
//! ```rust
//! let chirp_moisture =
//! components::chirp_i2c_moisture::ChirpI2cMoistureComponent::new(mux_i2c, 0x20).finalize(
//! components::chirp_i2c_moisture_component_static!(apollo3::iom::Iom<'static>),
//! );
//!
//! let moisture = components::moisture::MoistureComponent::new(
//! board_kernel,
//! capsules_extra::moisture::DRIVER_NUM,
//! chirp_moisture,
//! )
//! .finalize(components::moisture_component_static!(ChirpI2cMoistureType));
//! ```

use capsules_core::virtualizers::virtual_i2c::{I2CDevice, MuxI2C};
use capsules_extra::chirp_i2c_moisture::{ChirpI2cMoisture, BUFFER_SIZE};
use core::mem::MaybeUninit;
use kernel::component::Component;
use kernel::hil::i2c;

// Setup static space for the objects.
#[macro_export]
macro_rules! chirp_i2c_moisture_component_static {
($I:ty $(,)?) => {{
let i2c_device =
kernel::static_buf!(capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, $I>);
let i2c_buffer = kernel::static_buf!([u8; capsules_extra::chirp_i2c_moisture::BUFFER_SIZE]);
let chirp_i2c_moisture = kernel::static_buf!(
capsules_extra::chirp_i2c_moisture::ChirpI2cMoisture<
'static,
capsules_core::virtualizers::virtual_i2c::I2CDevice<$I>,
>
);

(i2c_device, i2c_buffer, chirp_i2c_moisture)
};};
}

pub type ChirpI2cMoistureComponentType<I> =
capsules_extra::chirp_i2c_moisture::ChirpI2cMoisture<'static, I>;

pub struct ChirpI2cMoistureComponent<I: 'static + i2c::I2CMaster<'static>> {
i2c_mux: &'static MuxI2C<'static, I>,
i2c_address: u8,
}

impl<I: 'static + i2c::I2CMaster<'static>> ChirpI2cMoistureComponent<I> {
pub fn new(i2c: &'static MuxI2C<'static, I>, i2c_address: u8) -> Self {
ChirpI2cMoistureComponent {
i2c_mux: i2c,
i2c_address,
}
}
}

impl<I: 'static + i2c::I2CMaster<'static>> Component for ChirpI2cMoistureComponent<I> {
type StaticInput = (
&'static mut MaybeUninit<I2CDevice<'static, I>>,
&'static mut MaybeUninit<[u8; BUFFER_SIZE]>,
&'static mut MaybeUninit<ChirpI2cMoisture<'static, I2CDevice<'static, I>>>,
);
type Output = &'static ChirpI2cMoisture<'static, I2CDevice<'static, I>>;

fn finalize(self, s: Self::StaticInput) -> Self::Output {
let chirp_i2c_moisture_i2c = s.0.write(I2CDevice::new(self.i2c_mux, self.i2c_address));
let i2c_buffer = s.1.write([0; BUFFER_SIZE]);

let chirp_i2c_moisture =
s.2.write(ChirpI2cMoisture::new(chirp_i2c_moisture_i2c, i2c_buffer));

chirp_i2c_moisture_i2c.set_client(chirp_i2c_moisture);
chirp_i2c_moisture.initialise();
chirp_i2c_moisture
}
}
2 changes: 2 additions & 0 deletions boards/components/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub mod button;
pub mod can;
pub mod ccs811;
pub mod cdc;
pub mod chirp_i2c_moisture;
pub mod console;
pub mod crc;
pub mod ctap;
Expand Down Expand Up @@ -59,6 +60,7 @@ pub mod lsm303dlhc;
pub mod lsm6dsox;
pub mod ltc294x;
pub mod mlx90614;
pub mod moisture;
pub mod mx25r6435f;
pub mod ninedof;
pub mod nonvolatile_storage;
Expand Down
69 changes: 69 additions & 0 deletions boards/components/src/moisture.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Licensed under the Apache License, Version 2.0 or the MIT License.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright Tock Contributors 2022.

//! Component for any moisture sensor.
//!
//! Usage
//! -----
//! ```rust
//! let moisture = components::moisture::MoistureComponent::new(
//! board_kernel,
//! capsules_extra::moisture::DRIVER_NUM,
//! chirp_moisture,
//! )
//! .finalize(components::moisture_component_static!(ChirpI2cMoistureType));
//! ```

use capsules_extra::moisture::MoistureSensor;
use core::mem::MaybeUninit;
use kernel::capabilities;
use kernel::component::Component;
use kernel::create_capability;
use kernel::hil;

#[macro_export]
macro_rules! moisture_component_static {
($H: ty $(,)?) => {{
kernel::static_buf!(capsules_extra::moisture::MoistureSensor<'static, $H>)
};};
}

pub type MoistureComponentType<H> = capsules_extra::moisture::MoistureSensor<'static, H>;

pub struct MoistureComponent<T: 'static + hil::sensors::MoistureDriver<'static>> {
board_kernel: &'static kernel::Kernel,
driver_num: usize,
sensor: &'static T,
}

impl<T: 'static + hil::sensors::MoistureDriver<'static>> MoistureComponent<T> {
pub fn new(
board_kernel: &'static kernel::Kernel,
driver_num: usize,
sensor: &'static T,
) -> MoistureComponent<T> {
MoistureComponent {
board_kernel,
driver_num,
sensor,
}
}
}

impl<T: 'static + hil::sensors::MoistureDriver<'static>> Component for MoistureComponent<T> {
type StaticInput = &'static mut MaybeUninit<MoistureSensor<'static, T>>;
type Output = &'static MoistureSensor<'static, T>;

fn finalize(self, s: Self::StaticInput) -> Self::Output {
let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);

let moisture = s.write(MoistureSensor::new(
self.sensor,
self.board_kernel.create_grant(self.driver_num, &grant_cap),
));

hil::sensors::MoistureDriver::set_client(self.sensor, moisture);
moisture
}
}
1 change: 1 addition & 0 deletions capsules/core/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ pub enum NUM {
AirQuality = 0x60007,
Pressure = 0x60008,
Distance = 0x60009,
Moisture = 0x6000A,

// Sensor ICs
Tsl2561 = 0x70000,
Expand Down
3 changes: 3 additions & 0 deletions capsules/extra/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ These implement a driver to setup and read various physical sensors.
- **[BMM150](src/bmm150.rs)**: Geomagnetic sensor.
- **[BMP280](src/bmp280.rs)**: Temperature (and air pressure) sensor.
- **[CCS811](src/ccs811.rs)**: VOC gas sensor.
- **[Chirp I2C Moisture](src/chirp_i2c_moisture.rs)**: I2C moisture sensor
from Chirp project.
- **[FXOS8700CQ](src/fxos8700cq.rs)**: Accelerometer and magnetometer.
- **[HS3003](src/hs3003.rs)**: Temperature and humidity sensor.
- **[HTS221](src/hts221.rs)**: Temperature and humidity sensor.
Expand Down Expand Up @@ -124,6 +126,7 @@ These provide common and better abstractions for userspace.
- **[Humidity](src/humidity.rs)**: Query humidity sensors.
- **[Key-Value Store](src/kv_driver.rs)**: Store key-value data.
- **[LED Matrix](src/led_matrix.rs)**: Control a 2D array of LEDs.
- **[Moisture](src/moisture.rs)**: Query moisture sensors.
- **[Pressure](src/pressure.rs)**: Pressure sensors.
- **[Proximity](src/proximity.rs)**: Proximity sensors.
- **[PWM](src/pwm.rs)**: Pulse-width modulation support.
Expand Down
Loading
Loading
0