#![no_main]
#![no_std]
use cortex_m::delay::Delay;
use cortex_m_rt::entry;
use critical_section::with;
use embedded_hal::digital::OutputPin;
use hal::{
adc::{Adc, AdcChannel, Align, CkMode, InputType, OperationMode},
clocks::Clocks,
gpio::{self, Edge, OutputSpeed, Pin, PinMode, PinState, Port},
low_power, pac,
prelude::*,
};
make_globals!((EXAMPLE_OUTPUT, Pin), (DEBOUNCE_TIMER, Timer<pac::TIM15>),);
fn example_type_sigs<O: OutputPin>(pin1: &mut O, pin2: &mut Pin) {
let setting = pin2.is_high();
pin1.set_low().ok();
}
pub fn setup_pins() {
let mut scl = Pin::new(Port::B, 6, PinMode::Alt(4));
scl.output_type(OutputType::OpenDrain);
let mut sda = Pin::new(Port::B, 7, PinMode::Alt(4));
sda.output_type(OutputType::OpenDrain);
let _sck = Pin::new(Port::A, 5, PinMode::Alt(5));
let _miso = Pin::new(Port::A, 6, PinMode::Alt(5));
let _mosi = Pin::new(Port::A, 7, PinMode::Alt(5));
let _uart_tx = Pin::new(Port::A, 9, PinMode::Alt(7));
let _uart_rx = Pin::new(Port::A, 10, PinMode::Alt(7));
let _usb_dm = Pin::new(Port::A, 11, PinMode::Alt(14));
let _usb_dp = Pin::new(Port::A, 12, PinMode::Alt(14));
let _adc_pin = Pin::new(Port::B, 0, PinMode::Analog);
let _dac_pin = Pin::new(Port::A, 4, PinMode::Analog);
let _pwm_pin = Pin::new(Port::A, 0, PinMode::Alt(1));
let mut up_btn = Pin::new(Port::B, 3, PinMode::Input);
up_btn.pull(Pull::Up);
up_btn.enable_interrupt(Edge::Falling);
let mut dn_btn = Pin::new(Port::A, 4, PinMode::Input);
dn_btn.pull(Pull::Up);
dn_btn.enable_interrupt(Edge::Falling);
}
fn init() {
let mut cp = cortex_m::Peripherals::take().unwrap();
let mut dp = pac::Peripherals::take().unwrap();
let clock_cfg = Clocks::default();
if clock_cfg.setup().is_err() {
defmt::error!("Unable to configure clocks due to a speed error.")
};
let mut delay = Delay::new(cp.SYST, clock_cfg.systick());
setup_pins();
let mut example_output = Pin::new(Port::B, 5, PinMode::Output);
let mut example_input = Pin::new(Port::B, 6, PinMode::Input);
example_output.output_speed(OutputSpeed::Medium);
let mut debounce_timer = Timer::new_tim15(dp.TIM15, 5., &clock_cfg);
debounce_timer.enable_interrupt(TimerInterrupt::Update);
example_type_sigs(&mut example_output, &mut example_input);
let state = example_input.get_state(); let state2 = example_input.is_high();
example_output.set_state(PinState::High);
example_output.set_high();
delay.delay_ms(500);
example_output.set_low();
init_globals!(
(EXAMPLE_OUTPUT, example_output),
(DEBOUNCE_TIMER, debounce_timer)
);
setup_nvic!([(EXTI3, 3), (EXTI4, 2), (TIM15, 3),], cp);
}
#[entry]
fn main() -> ! {
init();
loop {
low_power::sleep_now();
}
}
#[interrupt]
fn EXTI3() {
with(|cs| {
gpio::clear_exti_interrupt(3);
access_global!(DEBOUNCE_TIMER, debounce_timer, cs);
if debounce_timer.is_enabled() {
return;
}
access_global!(EXAMPLE_OUTPUT, example_output, cs);
example_output.set_high();
debounce_timer.enable();
});
}
#[interrupt]
fn EXTI4() {
with(|cs| {
gpio::clear_exti_interrupt(4);
access_global!(DEBOUNCE_TIMER, debounce_timer, cs);
if debounce_timer.is_enabled() {
return;
}
let mut p = EXAMPLE_OUTPUT.borrow(cs).borrow_mut();
let mut example_output = p.as_mut().unwrap();
example_output.set_low();
debounce_timer.enable();
});
}
#[interrupt]
fn TIM15() {
with(|cs| {
access_global!(DEBOUNCE_TIMER, debounce_timer, cs);
debounce_timer.clear_interrupt(TimerInterrupt::Update);
debounce_timer.disable();
});
}
#[defmt::panic_handler]
fn panic() -> ! {
cortex_m::asm::udf()
}