Firmware for the b-parasite board, but in Rust!
1use embassy_nrf::{
2 Peri, peripherals,
3 twim::{self, Twim},
4};
5use embassy_time::{Delay, Timer};
6use embedded_hal_async::i2c::{I2c, SevenBitAddress};
7use sachy_fmt::{error, info, unwrap};
8use sachy_shtc3::{Error as ShtError, Measurement, PowerMode, ShtC3};
9use static_cell::ConstStaticCell;
10
11use crate::{
12 Irqs,
13 state::{SHTC3_MEASUREMENT, START_MEASUREMENTS, Shtc3Measurement},
14};
15
16async fn measure<I>(sht: &mut ShtC3<I>) -> Result<Measurement, ShtError<I::Error>>
17where
18 I: I2c<SevenBitAddress>,
19{
20 let mut delay = Delay;
21
22 sht.wakeup_async(&mut delay).await?;
23
24 let divisor = 4;
25 let mut m = Measurement::default();
26
27 for _ in 0..divisor {
28 m += sht.measure_async(&mut delay).await?;
29
30 Timer::after_millis(5).await;
31 }
32
33 m /= divisor;
34
35 info!(
36 "Temp: {}C, Humi: {}%",
37 m.temperature.as_degrees_celsius(),
38 m.humidity.as_percent()
39 );
40
41 sht.sleep_async().await?;
42
43 Ok(m)
44}
45
46fn init_sht3<'scope>(
47 spio: Peri<'scope, peripherals::TWISPI0>,
48 sda: Peri<'scope, peripherals::P0_24>,
49 scl: Peri<'scope, peripherals::P0_13>,
50 ram: &'scope mut [u8; 16],
51) -> ShtC3<Twim<'scope>> {
52 let config = twim::Config::default();
53 let twi = Twim::new(spio, Irqs, sda, scl, config, ram);
54
55 ShtC3::new(twi, PowerMode::LowPower)
56}
57
58#[embassy_executor::task]
59pub async fn task(
60 mut spio: Peri<'static, peripherals::TWISPI0>,
61 mut sda: Peri<'static, peripherals::P0_24>,
62 mut scl: Peri<'static, peripherals::P0_13>,
63) {
64 static RAM_BUFFER: ConstStaticCell<[u8; 16]> = ConstStaticCell::new([0; 16]);
65 let ram = RAM_BUFFER.take();
66
67 let mut watcher = unwrap!(START_MEASUREMENTS.receiver());
68
69 loop {
70 watcher.changed().await;
71
72 let mut sht = init_sht3(spio.reborrow(), sda.reborrow(), scl.reborrow(), ram);
73
74 match measure(&mut sht).await {
75 Ok(measurement) => {
76 SHTC3_MEASUREMENT.signal(Shtc3Measurement::new(measurement));
77 }
78 Err(e) => {
79 error!("SHTC3 error: {:?}", e);
80
81 // Attempt to reset the sensor
82 if let Err(e) = sht.reset_async(&mut Delay).await {
83 error!("SHTC3 reset error: {:?}", e);
84 }
85 }
86 }
87
88 drop(sht);
89 }
90}