#![no_main]
#![no_std]
use core::cell::{Cell, RefCell};
use cortex_m::{
interrupt::{free, Mutex},
peripheral::NVIC,
};
use cortex_m_rt::entry;
use stm32_hal::{
adc::{Adc, AdcChannel},
clocks::Clocks,
gpio::{Edge, Pin, Port, PinMode},
low_power,
pac::{self, ADC1, EXTI},
prelude::*,
rtc::{Rtc, RtcClockSource, RtcConfig},
timer::{Timer, TimerInterrupt},
};
static SENSOR_READING: Mutex<Cell<f32>> = Mutex::new(Cell::new(335.));
static BOUNCING: Mutex<Cell<bool>> = Mutex::new(Cell::new(false));
static ADC: Mutex<RefCell<Option<ADC<ADC1>>>> = Mutex::new(RefCell::new(None));
#[entry]
fn main() -> ! {
let mut cp = cortex_m::Peripherals::take().unwrap();
let mut dp = pac::Peripherals::take().unwrap();
let clock_cfg = Clocks::default();
clock_cfg.setup(&mut dp.RCC, &mut dp.FLASH).unwrap();
let mut button = Pin::new(Port::A, 0, PinMode::Input);
button.enable_interrupt(Edge::Falling);
let mut timer = Timer::new_tim3(dp.TIM3, 0.2, &clock_cfg);
timer.enable_interrupt(TimerInterrupt::Update); timer.enable();
let mut debounce_timer = Timer::new_tim15(dp.TIM15, 5., &clock_cfg);
debounce_timer.enable_interrupt(TimerInterrupt::Update);
let mut rtc = Rtc::new(
dp.RTC,
&mut dp.PWR,
RtcConfig {
clock_source: RtcClockSource::Lse,
..Default::default()
},
);
rtc.set_wakeup(&mut dp.EXTI, 30.);
let mut adc = Adc::new_adc1(
dp.ADC1,
&mut dp.ADC_COMMON,
adc::CkMode::default(),
&clock_cfg,
);
free(|cs| {
ADC.borrow(cs).replace(Some(adc));
});
unsafe {
NVIC::unmask(pac::Interrupt::EXTI0); NVIC::unmask(pac::Interrupt::TIM3); NVIC::unmask(pac::Interrupt::TIM15); NVIC::unmask(pac::Interrupt::RTC_WKUP);
cp.NVIC.set_priority(pac::Interrupt::EXTI0, 0);
cp.NVIC.set_priority(pac::Interrupt::TIM3, 1);
}
loop {
low_power::stop(
&mut cp.SCB,
&mut dp.PWR,
low_power::StopMode::Two,
&clock_cfg,
);
clocks.reselect_input();
}
}
#[interrupt]
fn EXTI0() {
free(|cs| {
unsafe {
(*pac::EXTI::ptr()).pr1.modify(|_, w| w.pr0().set_bit());
}
let bouncing = BOUNCING.borrow(cs);
if bouncing.get() {
return;
}
unsafe { (*pac::TIM15::ptr()).cr1.modify(|_, w| w.cen().set_bit()) }
bouncing.set(true);
let mut s = ADC.borrow(cs).borrow_mut();
let sensor = s.as_mut().unwrap();
let reading = sensor.read(AdcChannel::C1).unwrap();
SENSOR_READING.borrow(cs).replace(reading);
});
}
#[interrupt]
fn RTC_WKUP() {
free(|cs| {
unsafe {
(*pac::EXTI::ptr()).pr1.modify(|_, w| w.pr20().set_bit());
(*pac::RTC::ptr()).wpr.write(|w| w.bits(0xCA));
(*pac::RTC::ptr()).wpr.write(|w| w.bits(0x53));
(*pac::RTC::ptr()).cr.modify(|_, w| w.wute().clear_bit());
(*pac::RTC::ptr()).isr.modify(|_, w| w.wutf().clear_bit());
(*pac::RTC::ptr()).cr.modify(|_, w| w.wute().set_bit());
(*pac::RTC::ptr()).wpr.write(|w| w.bits(0xFF));
}
});
}
#[interrupt]
fn TIM3() {
free(|cs| {
unsafe { (*pac::TIM3::ptr()).sr.modify(|_, w| w.uif().set_bit()) }
});
}
#[interrupt]
fn TIM15() {
free(|cs| {
unsafe { (*pac::TIM15::ptr()).sr.modify(|_, w| w.uif().set_bit()) }
BOUNCING.borrow(cs).set(false);
unsafe { (*pac::TIM15::ptr()).cr1.modify(|_, w| w.cen().clear_bit()) }
});
}