| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- #![no_main]
- #![no_std]
-
- mod display;
- mod information;
- mod pins;
- mod radio;
- mod sensors;
-
- // TODO: Enable warnings again.
- #[allow(unused)]
- mod assets {
- include!(concat!(env!("OUT_DIR"), "/assets.rs"));
- }
-
- use mkl25z4_hal::clocks::ClockConfiguration;
- use mkl25z4_hal::time::{CopyableMonoTimer, NonCopyableMonoTimer, U32Ext};
- use panic_semihosting as _;
-
- use display::{Display, DisplayState};
- use information::{Information, TemperatureHumidity};
- use pins::{BME280Pins, DisplayBmeSpi};
- use radio::Radio;
-
- #[rtfm::app(device = mkl25z4_hal::mkl25z4, peripherals = true)]
- const APP: () = {
- struct Resources {
- info: Information,
- display_state: DisplayState,
- display: Display,
- display_bme_spi: Option<DisplayBmeSpi>,
- bme_pins: Option<BME280Pins>,
- radio: Option<Radio>,
- time: CopyableMonoTimer,
- }
-
- #[init(spawn = [fetch_update])]
- fn init(ctx: init::Context) -> init::LateResources {
- let mut sim = ctx.device.SIM;
- mkl25z4_hal::watchdog::disable(&mut sim);
- let clocks = ClockConfiguration::new()
- .use_irc()
- .core_clock(24.mhz())
- .bus_clock(24.mhz())
- .apply(&mut sim, ctx.device.OSC0, ctx.device.MCG);
-
- let mut pins = pins::Pins::configure(
- &mut sim,
- clocks,
- ctx.device.GPIOA,
- ctx.device.GPIOB,
- ctx.device.GPIOC,
- ctx.device.GPIOD,
- ctx.device.GPIOE,
- ctx.device.SPI0,
- ctx.device.SPI1,
- );
-
- let time =
- CopyableMonoTimer::new(NonCopyableMonoTimer::new(ctx.device.PIT, clocks, &mut sim));
-
- let display = Display::init(pins.display, &mut pins.display_bme_spi, time);
-
- let radio = Radio::init(pins.nrf, time);
-
- // Fetch the first update.
- ctx.spawn.fetch_update().ok();
-
- init::LateResources {
- info: Information {
- time: 0,
- valid: false,
- inside: None,
- outside: None,
- bathroom: None,
- pressure: None,
- },
- display_state: DisplayState{
- // TODO
- },
- display,
- display_bme_spi: Some(pins.display_bme_spi),
- bme_pins: Some(pins.bme),
- radio: Some(radio),
- time,
- }
- }
-
- #[task(binds = LPTMR0, priority = 3, spawn = [fetch_update])]
- fn lptmr0_interrupt(ctx: lptmr0_interrupt::Context) {
- // Restart the timer.
- // TODO
-
- // Trigger an update of the displayed values.
- ctx.spawn.fetch_update().ok();
- }
-
- #[task(binds = LLWU, priority = 3)]
- fn llwu_interrupt(_: llwu_interrupt::Context) {
- // TODO
- }
-
- #[task(priority = 1, spawn = [update_display], resources = [info, bme_pins, display_bme_spi, &time, radio])]
- fn fetch_update(mut ctx: fetch_update::Context) {
- // Fetch local updates.
- let time = ctx.resources.time.clone();
- let pins = ctx.resources.bme_pins.take().unwrap();
- let (pins, values) = ctx.resources.display_bme_spi.lock(|display_bme_spi| {
- let spi = display_bme_spi.take().unwrap();
- let (pins, spi, values) = sensors::bme280(pins, spi, time);
- *display_bme_spi = Some(spi);
- (pins, values)
- });
- *ctx.resources.bme_pins = Some(pins);
-
- // Send local measurements to the base station. This needs to be done before fetching data
- // from the base station as the base station might return the data to us.
- let mut radio = ctx.resources.radio.as_mut().unwrap().enable();
- radio.send_sensor_values(values);
- // TODO
-
- // Fetch updates via radio.
- // TODO
- ctx.resources.info.lock(|info| {
- info.inside = Some(TemperatureHumidity {
- temperature: values.temperature,
- humidity: values.humidity,
- });
- info.pressure = Some(values.pressure);
- });
-
- // If the update failed, simply increment the time and place a hint that
- // the information might be invalid.
- // TODO
-
- // Update the display to show the new values.
- ctx.spawn.update_display().ok();
- }
-
- #[task(priority = 2, resources = [info, display_state, display, display_bme_spi, &time])]
- fn update_display(ctx: update_display::Context) {
- ctx.resources.display.update(
- &ctx.resources.display_state,
- &ctx.resources.info,
- ctx.resources.display_bme_spi.as_mut().unwrap(),
- ctx.resources.time.clone(),
- );
- }
-
- #[idle]
- fn idle(_cx: idle::Context) -> ! {
- // Sleep
- loop {
- // wfi needs to be disabled for GDB
- /*// add some side effect to prevent this from turning into a UDF instruction
- // see rust-lang/rust#28728 for details
- atomic::compiler_fence(Ordering::SeqCst);*/
- cortex_m::asm::wfi();
- }
- }
-
- extern "C" {
- fn I2C0();
- fn I2C1();
- }
- };
|