#![deny(unsafe_code)]
#![no_main]
#![no_std]
#[cfg(not(feature = "env_logging"))]
use panic_rtt_target as _;
use rtt_target::rtt_init_print;
#[cfg(feature = "stm32f4xx")]
use stm32f4 as _;
#[cfg(feature = "stm32f4xx")]
use stm32f4xx_hal as hal;
#[cfg(feature = "stm32f4xx")]
use stm32f4xx_hal::stm32 as device;
#[cfg(feature = "stm32f4xx")]
use hal::{gpio::AlternateOD, i2c::I2c};
#[cfg(feature = "stm32f7xx")]
use stm32f7 as _;
#[cfg(feature = "stm32f7xx")]
use stm32f7xx_hal as hal;
#[cfg(feature = "stm32f7xx")]
use stm32f7xx_hal::device;
#[cfg(feature = "stm32f7xx")]
use hal::{
gpio::Alternate,
i2c::{BlockingI2c, Mode},
};
use hal::{gpio::GpioExt, gpio::AF4, rcc::RccExt, time::U32Ext};
#[cfg(feature = "stm32f7xx")]
use rtic::export::DWT;
use drogue_bme680::{Address, Bme680Sensor, CalibrationInformation};
use log::LevelFilter;
use rtt_logger::RTTLogger;
static LOGGER: RTTLogger = RTTLogger::new(LevelFilter::Info);
pub trait I2cConfig<Instance> {
type SclPin;
type SdaPin;
}
#[cfg(feature = "stm32f4xx")]
type I2CInstance = stm32f4::stm32f411::I2C1;
#[cfg(feature = "stm32f4xx")]
impl<Instance> I2cConfig<Instance> for I2CInstance {
type SclPin = hal::gpio::gpiob::PB8<AlternateOD<AF4>>;
type SdaPin = hal::gpio::gpiob::PB9<AlternateOD<AF4>>;
}
#[cfg(feature = "stm32f4xx")]
type I2cBmeInstance = I2c<
I2CInstance,
(
<I2CInstance as I2cConfig<I2CInstance>>::SclPin,
<I2CInstance as I2cConfig<I2CInstance>>::SdaPin,
),
>;
#[cfg(feature = "stm32f7xx")]
type I2CInstance = stm32f7::stm32f7x3::I2C2;
#[cfg(feature = "stm32f7xx")]
impl<Instance> I2cConfig<Instance> for I2CInstance {
type SclPin = hal::gpio::gpioh::PH4<Alternate<AF4>>;
type SdaPin = hal::gpio::gpioh::PH5<Alternate<AF4>>;
}
#[cfg(feature = "stm32f7xx")]
type I2cBmeInstance = BlockingI2c<
I2CInstance,
<I2CInstance as I2cConfig<I2CInstance>>::SclPin,
<I2CInstance as I2cConfig<I2CInstance>>::SdaPin,
>;
#[rtic::app(device = crate::device, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)]
const APP: () = {
struct Resources {
i2c: Option<I2cBmeInstance>,
}
#[init]
fn init(mut cx: init::Context) -> init::LateResources {
rtt_init_print!(NoBlockSkip, 4096);
log::set_logger(&LOGGER).unwrap();
log::set_max_level(log::LevelFilter::Trace);
log::info!("Starting up...");
cx.core.DCB.enable_trace();
#[cfg(feature = "stm32f7xx")]
DWT::unlock();
cx.core.DWT.enable_cycle_counter();
let device: device::Peripherals = cx.device;
#[cfg(feature = "stm32f4xx")]
let rcc = device.RCC.constrain();
#[cfg(feature = "stm32f7xx")]
let mut rcc = device.RCC.constrain();
#[cfg(feature = "stm32f4xx")]
let clocks = rcc.cfgr.sysclk(50.mhz()).freeze();
#[cfg(feature = "stm32f7xx")]
let clocks = rcc.cfgr.sysclk(216.mhz()).freeze();
#[cfg(feature = "stm32f4xx")]
let gpiob = device.GPIOB.split();
#[cfg(feature = "stm32f7xx")]
let gpioh = device.GPIOH.split();
#[cfg(feature = "stm32f4xx")]
let (sda, scl) = {
let sda = gpiob.pb9.into_alternate_af4_open_drain();
let scl = gpiob.pb8.into_alternate_af4_open_drain();
(sda, scl)
};
#[cfg(feature = "stm32f7xx")]
let (sda, scl) = {
let sda = gpioh.ph5.into_alternate_af4();
let scl = gpioh.ph4.into_alternate_af4();
(sda, scl)
};
log::info!("Init I2C ...");
#[cfg(feature = "stm32f4xx")]
let i2c = I2c::i2c1(device.I2C1, (scl, sda), 100.khz(), clocks);
#[cfg(feature = "stm32f7xx")]
let i2c = BlockingI2c::i2c2(
device.I2C2,
(scl, sda),
Mode::standard(100_000.hz()),
clocks,
&mut rcc.apb1,
100,
);
init::LateResources { i2c: Some(i2c) }
}
#[idle(resources=[i2c])]
fn idle(cx: idle::Context) -> ! {
let i2c = cx.resources.i2c.take().unwrap();
let mut bme680 = Bme680Sensor::from(i2c, Address::Secondary).unwrap();
let mut calib = bme680.get_calibration_data().unwrap();
log::info!("Calib: {:#?}", CalibrationInformation(&mut calib.0[..]));
loop {
cortex_m::asm::nop();
}
}
};