From 2bff0a54c73fb19d67b1a20892e88f404450ff37 Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Sat, 4 Oct 2025 15:47:26 +0200 Subject: [PATCH] Refactor HumiditySensor to directly take Twim() as argument; Move measurement into separate task --- src/bin/temp_rh_measurement.rs | 108 +++++++++++---------------------- 1 file changed, 34 insertions(+), 74 deletions(-) diff --git a/src/bin/temp_rh_measurement.rs b/src/bin/temp_rh_measurement.rs index d6b119d..78272e6 100644 --- a/src/bin/temp_rh_measurement.rs +++ b/src/bin/temp_rh_measurement.rs @@ -1,83 +1,26 @@ #![no_std] #![no_main] +use embassy_nrf::peripherals::TWISPI0; use embassy_time::Timer; use nrf_softdevice::Softdevice; use defmt::*; use embassy_executor::Spawner; -use embassy_nrf::gpio::Pin as GpioPin; -use embassy_nrf::interrupt; -use embassy_nrf::twim::{self, Instance as TwimInstance, InterruptHandler, Twim}; -use embassy_nrf::{bind_interrupts, peripherals, Peripheral}; +use embassy_nrf::gpio::{Level, Output, OutputDrive}; +use embassy_nrf::twim; +use embassy_nrf::{bind_interrupts, peripherals}; use {defmt_rtt as _, panic_probe as _}; -struct I2cDriver<'a, T: TwimInstance> { +struct GenericTempHumiditySensor { address: u8, - twim: Twim<'a, T>, -} - -trait Driver { - /// The msg being mutable ensures that it doesn't have to be copied into RAM for DMA access, as - /// it is already there - fn write(&mut self, msg: &mut [u8]); - fn read(&mut self, buffer: &mut [u8]); -} - -impl<'a, T: TwimInstance> Driver for I2cDriver<'a, T> { - fn write(&mut self, msg: &mut [u8]) { - unwrap!(self.twim.blocking_write(self.address, &mut *msg)); - } - - fn read(&mut self, buffer: &mut [u8]) { - unwrap!(self.twim.blocking_read(self.address, &mut *buffer)); - } -} - -impl<'a, T: TwimInstance> I2cDriver<'a, T> { - fn new( - address: u8, - peripheral: impl Peripheral

+ 'a, - sda: impl Peripheral

+ 'a, - scl: impl Peripheral

+ 'a, - _irq: impl interrupt::typelevel::Binding> + 'a, - ) -> Self { - let config = twim::Config::default(); - let twim = Twim::new(peripheral, _irq, sda, scl, config); - - Self { address, twim } - } -} - -struct MockI2cDriver; - -impl Driver for MockI2cDriver { - fn write(&mut self, _: &mut [u8]) {} - - fn read(&mut self, buffer: &mut [u8]) { - buffer[0] = 127; - buffer[1] = 128; - buffer[2] = 129; - buffer[3] = 130; - buffer[4] = 131; - buffer[5] = 132; - } -} - -impl MockI2cDriver { - fn new() -> Self { - Self {} - } -} - -struct TempHumiditySensor { - driver: T, + driver: twim::Twim<'static, T>, } // TODO: Implement CRC checks -impl TempHumiditySensor { - fn new(driver: T) -> Self { - Self { driver } +impl GenericTempHumiditySensor { + fn new(address: u8, driver: twim::Twim<'static, T>) -> Self { + Self { address, driver } } /// The procedure for reading out the temperature and humidity and converting them to floats is @@ -85,9 +28,9 @@ impl TempHumiditySensor { async fn read_temp_and_humidity(&mut self) -> (f32, f32) { let mut buf = [0u8; 6]; - self.driver.write(&mut [0xFD]); + unwrap!(self.driver.blocking_write(self.address, &mut [0xFD])); Timer::after_millis(10).await; - self.driver.read(&mut buf); + unwrap!(self.driver.blocking_read(self.address, &mut buf)); let temp_int = u16::from_be_bytes([buf[0], buf[1]]); let temp_float: f32 = -45f32 + 175f32 * (temp_int as f32 / (2u32.pow(16) - 1) as f32); @@ -103,16 +46,33 @@ bind_interrupts!(struct Irqs { SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => twim::InterruptHandler; }); -#[embassy_executor::main] -async fn main(_spawner: Spawner) { - let p = embassy_nrf::init(Default::default()); - - let driver = I2cDriver::new(0x44, p.TWISPI0, p.P0_14, p.P0_13, Irqs); - let mut sensor = TempHumiditySensor::new(driver); +type TempHumiditySensor = GenericTempHumiditySensor; +#[embassy_executor::task] +async fn measurement_task(mut sensor: TempHumiditySensor) { loop { let (temp, humidity) = sensor.read_temp_and_humidity().await; println!("{} °C\t{} %", temp, humidity); Timer::after_millis(50).await; } } + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + let p = embassy_nrf::init(Default::default()); + + let config = twim::Config::default(); + let twi = twim::Twim::new(p.TWISPI0, Irqs, p.P0_14, p.P0_13, config); + let sensor = TempHumiditySensor::new(0x44, twi); + + let mut led = Output::new(p.P0_20, Level::Low, OutputDrive::Standard); + + unwrap!(spawner.spawn(measurement_task(sensor))); + + loop { + led.set_high(); + Timer::after_millis(500).await; + led.set_low(); + Timer::after_millis(500).await; + } +}