-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpfm.rs
93 lines (73 loc) · 2.74 KB
/
pfm.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#![no_main]
#![no_std]
use panic_halt as _;
use stm32f7xx_hal::{
gpio::{self, Output, PushPull},
pac::{interrupt, Interrupt, Peripherals, TIM2},
prelude::*,
timer::{CounterUs, Event},
};
use core::cell::RefCell;
use cortex_m::interrupt::Mutex;
use cortex_m_rt::entry;
// NOTE You can uncomment 'hprintln' here and in the code below for a bit more
// verbosity at runtime, at the cost of throwing off the timing of the blink
// (using 'semihosting' for printing debug info anywhere slows program
// execution down)
//use cortex_m_semihosting::hprintln;
// A type definition for the GPIO pin to be used for our LED
// For the onboard nucleo LED, use PA5 or PB13 depending your model
type LedPin = gpio::PB0<Output<PushPull>>;
// Make LED pin globally available
static G_LED: Mutex<RefCell<Option<LedPin>>> = Mutex::new(RefCell::new(None));
// Make timer interrupt registers globally available
static G_TIM: Mutex<RefCell<Option<CounterUs<TIM2>>>> = Mutex::new(RefCell::new(None));
// Define an interupt handler, i.e. function to call when interrupt occurs.
// This specific interrupt will "trip" when the timer TIM2 times out
#[interrupt]
unsafe fn TIM2() {
static mut LED: Option<LedPin> = None;
static mut TIM: Option<CounterUs<TIM2>> = None;
let led = LED.get_or_insert_with(|| {
cortex_m::interrupt::free(|cs| {
// Move LED pin here, leaving a None in its place
G_LED.borrow(cs).replace(None).unwrap()
})
});
let tim = TIM.get_or_insert_with(|| {
cortex_m::interrupt::free(|cs| {
// Move LED pin here, leaving a None in its place
G_TIM.borrow(cs).replace(None).unwrap()
})
});
led.toggle();
let _ = tim.wait();
}
#[entry]
fn main() -> ! {
let dp = Peripherals::take().unwrap();
let rcc = dp.RCC.constrain();
let clocks = rcc.cfgr.sysclk(96.MHz()).pclk1(48.MHz()).freeze();
// Configure PA5 pin to blink LED
let gpioa = dp.GPIOB.split();
let mut led = gpioa.pb0.into_push_pull_output();
led.set_high(); // Turn off
// Move the pin into our global storage
cortex_m::interrupt::free(|cs| *G_LED.borrow(cs).borrow_mut() = Some(led));
// Set up a timer expiring after 1s
let mut timer = dp.TIM2.counter(&clocks);
timer.start(100.millis()).unwrap();
// Generate an interrupt when the timer expires
timer.listen(Event::Update);
// Move the timer into our global storage
cortex_m::interrupt::free(|cs| *G_TIM.borrow(cs).borrow_mut() = Some(timer));
//enable TIM2 interrupt
unsafe {
cortex_m::peripheral::NVIC::unmask(Interrupt::TIM2);
}
#[allow(clippy::empty_loop)]
loop {
// Uncomment if you want to make controller sleep
// cortex_m::asm::wfi();
}
}