Browse Source

First shot at making conditional compilation for bme680

'usedrogue' cargo feature can be used to use drogue-bme680 instead of bme680.
Currently, works better as it reports a temperature value.
dev/doc
Marc Poulhiès 2 years ago
parent
commit
cc814517dd
  1. 11
      Cargo.toml
  2. 65
      src/main.rs

11
Cargo.toml

@ -25,7 +25,6 @@ panic = "abort"
ws2812-spi = "0.3"
rotary-encoder-hal = {git = "https://github.com/dkm/rotary-encoder-hal" , features = ["table-decoder"] }
debouncr = "0.2"
bme680 = "0.5"
ufmt = "0.1"
##ws2812-spi = {git = "https://github.com/smart-leds-rs/ws2812-spi-rs"}
## tm4c123x-hal = {git = "https://github.com/thejpster/tm4c-hal.git", features = ["rt"]}
@ -50,6 +49,10 @@ smart-leds = "0.3"
epd-waveshare = {git = "https://github.com/caemor/epd-waveshare.git", rev="87e63741ef9335439d97f587a781630077be2515" }
embedded-graphics = "0.6"
cortex-m-rtic = "0.5"
bme680 = { version = "0.5", optional = true }
drogue-bme680 = { version = "0.3", optional = true }
embedded-time = { version = "0.10", optional = true }
[dependencies.heapless]
version = "0.5"
@ -76,7 +79,9 @@ version = "0.2"
features = ["unproven"]
[features]
default = []
default = [ "bme680" ]
usedrogue = [ "drogue-bme680", "embedded-time" ]
## This will use semihosting for printing debug trace.
usesemihosting = []
usesemihosting = [ "default" ]

65
src/main.rs

@ -17,14 +17,25 @@ extern crate tm4c123x_hal;
extern crate tm4c_hal;
extern crate ws2812_spi;
#[cfg(feature = "usedrogue")]
extern crate embedded_time;
use heapless::{consts::U5, String};
use ufmt::uwrite;
use rtic::cyccnt::U32Ext as _;
#[cfg(not(feature = "usedrogue"))]
use bme680::{Bme680, I2CAddress, IIRFilterSize, OversamplingSetting, PowerMode, SettingsBuilder};
#[cfg(feature = "usedrogue")]
use drogue_bme680::{
Address, Bme680Controller, Bme680Sensor, Configuration, DelayMsWrapper, StaticProvider,
};
#[cfg(feature = "usedrogue")]
use embedded_time::duration::Milliseconds;
use core::time::Duration;
use embedded_hal::{
@ -96,6 +107,13 @@ pub struct SimpleAsmDelay {
freq: u32,
}
#[cfg(feature = "usedrogue")]
impl drogue_bme680::Delay for SimpleAsmDelay {
fn delay_ms(&self, duration_ms: u16) {
cortex_m::asm::delay(self.freq * cast::u32(duration_ms) * 1000 / 1_000_000)
}
}
impl DelayUs<u32> for SimpleAsmDelay {
fn delay_us(&mut self, us: u32) {
cortex_m::asm::delay(self.freq * us / 1_000_000)
@ -192,8 +210,12 @@ type I2c1T = I2c<
PA7<AlternateFunction<AF3, OpenDrain<Floating>>>,
),
>;
#[cfg(not(feature = "usedrogue"))]
type Bme680T = Bme680<I2c1T, SimpleAsmDelay>;
#[cfg(feature = "usedrogue")]
type Bme680T = Bme680Controller<I2c1T, SimpleAsmDelay, StaticProvider>;
// spi for WS2812
type Spi0T = Spi<
SSI0,
@ -398,6 +420,7 @@ const APP: () = {
&sc.power_control,
);
#[cfg(not(feature = "usedrogue"))]
let mut bme680 = Bme680::init(
i2c_bme680,
SimpleAsmDelay { freq: 80_000_000 },
@ -405,6 +428,7 @@ const APP: () = {
)
.unwrap();
#[cfg(not(feature = "usedrogue"))]
let settings = SettingsBuilder::new()
.with_humidity_oversampling(OversamplingSetting::OS2x)
.with_pressure_oversampling(OversamplingSetting::OS4x)
@ -413,8 +437,17 @@ const APP: () = {
.with_gas_measurement(Duration::from_millis(1500), 320, 25)
.with_run_gas(true)
.build();
#[cfg(not(feature = "usedrogue"))]
bme680.set_sensor_settings(settings).unwrap();
#[cfg(feature = "usedrogue")]
let bme680_sensor = Bme680Sensor::from(i2c_bme680, Address::Primary).unwrap();
#[cfg(feature = "usedrogue")]
let mut bme680 =
Bme680Controller::new(bme680_sensor, SimpleAsmDelay { freq: 80_000_000 }, Configuration::standard(), StaticProvider(25))
.unwrap();
let mut delay = SimpleAsmDelay { freq: 80_000_000 };
let mut epd =
EPD2in13::new(&mut spi0, cs_pin, busy_pin, dc_pin, rst_pin, &mut delay).unwrap();
@ -901,6 +934,7 @@ const APP: () = {
fn refresh_bme680(cx: refresh_bme680::Context) {
let (temp, _pres, humid, _gas): (i32, i32, i32, i32);
#[cfg(not(feature = "usedrogue"))]
if let Ok(_) = cx.resources.bme680.set_sensor_mode(PowerMode::ForcedMode) {
let (data, _state) = cx.resources.bme680.get_sensor_data().unwrap();
@ -918,7 +952,36 @@ const APP: () = {
humid = 0i32;
_gas = 0i32;
*cx.resources.i2c_error += 1;
debug_only! {hprintln!("I2C error for bme").unwrap()}
debug_only! {hprintln!("I2C bme680 error for bme").unwrap()}
}
#[cfg(feature = "usedrogue")]
if let Ok(opt_data) = cx.resources.bme680.measure(5, Milliseconds(50)) {
if let Some(data) = opt_data {
temp = data.temperature as i32;
_pres = if let Some(f) = data.pressure {f as i32 } else { 0 };
humid = data.humidity as i32;
_gas = data.gas_resistance as i32;
} else {
temp = 0i32;
_pres = 0i32;
humid = 0i32;
_gas = 0i32;
*cx.resources.i2c_error += 1;
debug_only! {hprintln!("I2C OK, but empty result from drogue_bme680").unwrap()}
}
} else {
// For some reason, the bme680 seems to stop responding and a hw
// reset is needed to make it work again. Maybe caused by the
// current spaghetti setup used for prototyping.
// Simply count the errors
temp = 0i32;
_pres = 0i32;
humid = 0i32;
_gas = 0i32;
*cx.resources.i2c_error += 1;
debug_only! {hprintln!("I2C error drogue_bme680 for bme").unwrap()}
}
let cur_i2c_error = *cx.resources.i2c_error;

Loading…
Cancel
Save