Skip to content

Commit e809257

Browse files
Merge #222
222: add blinky_timer_irq example r=therealprof a=YruamaLairba Hello, i adapted the blinky_timer_irq example of stm32f1xx-hal. The source work when in a dedicated project, but i don't know how to make it work "inplace". I mean i can compile it using `cargo build --features="rt stm32f411" --example blinky-timer-irq` but when i'm using `gdb-multiarch -q target/thumbv7em-none-eabihf/debug/examples/blinky-timer-irq` and doing `target remote :3333` i get `Dwarf Error: Cannot find DIE at 0xe3b0 referenced from DIE at 0xe7e7 [in module /home/amaury/projet/rust/embed/stm32f4xx-hal/target/thumbv7em-none-eabihf/debug/examples/blinky-timer-irq]` I don't know what it mean. I tryed to change memory.x and add the build.rs, don't work. Co-authored-by: Yruama_Lairba <yruama_lairba@hotmail.com>
2 parents 1dabe77 + 93c6e6f commit e809257

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ debug = true
9999
lto = true
100100
opt-level = "s"
101101

102+
[[example]]
103+
name = "blinky-timer-irq"
104+
required-features = ["rt", "stm32f411"]
105+
102106
[[example]]
103107
name = "usb_serial"
104108
required-features = ["rt", "stm32f401", "usb_fs"]

examples/blinky-timer-irq.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
//! blinky timer using interrupts on TIM2, adapted from blinky_timer_irq.rs example from
2+
//! stm32f1xx-hal
3+
//!
4+
//! This assumes that a LED is connected to pa5 (sck/d13) as is the case on most nucleo board.
5+
6+
#![no_main]
7+
#![no_std]
8+
9+
use panic_halt as _;
10+
11+
use stm32f4xx_hal as hal;
12+
13+
use crate::hal::{
14+
gpio::{gpioa, Output, PushPull},
15+
prelude::*,
16+
stm32::{interrupt, Interrupt, Peripherals, TIM2},
17+
timer::{Event, Timer},
18+
};
19+
20+
use core::cell::RefCell;
21+
use cortex_m::{asm::wfi, interrupt::Mutex};
22+
use cortex_m_rt::entry;
23+
use embedded_hal::digital::v2::OutputPin;
24+
use embedded_hal::timer::CountDown;
25+
26+
// NOTE You can uncomment 'hprintln' here and in the code below for a bit more
27+
// verbosity at runtime, at the cost of throwing off the timing of the blink
28+
// (using 'semihosting' for printing debug info anywhere slows program
29+
// execution down)
30+
//use cortex_m_semihosting::hprintln;
31+
32+
// A type definition for the GPIO pin to be used for our LED
33+
// For the onboard nucleo LED, use gpioa::PA5 or gpiob::PB13 depending your model
34+
type LEDPIN = gpioa::PA5<Output<PushPull>>;
35+
36+
// Make LED pin globally available
37+
static G_LED: Mutex<RefCell<Option<LEDPIN>>> = Mutex::new(RefCell::new(None));
38+
39+
// Make timer interrupt registers globally available
40+
static G_TIM: Mutex<RefCell<Option<Timer<TIM2>>>> = Mutex::new(RefCell::new(None));
41+
42+
// Define an interupt handler, i.e. function to call when interrupt occurs.
43+
// This specific interrupt will "trip" when the timer TIM2 times out
44+
#[interrupt]
45+
fn TIM2() {
46+
static mut LED: Option<LEDPIN> = None;
47+
static mut TIM: Option<Timer<TIM2>> = None;
48+
49+
let led = LED.get_or_insert_with(|| {
50+
cortex_m::interrupt::free(|cs| {
51+
// Move LED pin here, leaving a None in its place
52+
G_LED.borrow(cs).replace(None).unwrap()
53+
})
54+
});
55+
56+
let tim = TIM.get_or_insert_with(|| {
57+
cortex_m::interrupt::free(|cs| {
58+
// Move LED pin here, leaving a None in its place
59+
G_TIM.borrow(cs).replace(None).unwrap()
60+
})
61+
});
62+
63+
let _ = led.toggle();
64+
let _ = tim.wait();
65+
}
66+
67+
#[entry]
68+
fn main() -> ! {
69+
let dp = Peripherals::take().unwrap();
70+
71+
let rcc = dp.RCC.constrain();
72+
let clocks = rcc.cfgr.sysclk(16.mhz()).pclk1(8.mhz()).freeze();
73+
74+
// Configure PA5 pin to blink LED
75+
let gpioa = dp.GPIOA.split();
76+
let mut led = gpioa.pa5.into_push_pull_output();
77+
let _ = led.set_high(); // Turn off
78+
79+
// Move the pin into our global storage
80+
cortex_m::interrupt::free(|cs| *G_LED.borrow(cs).borrow_mut() = Some(led));
81+
82+
// Set up a timer expiring after 1s
83+
let mut timer = Timer::tim2(dp.TIM2, 1.hz(), clocks);
84+
85+
// Generate an interrupt when the timer expires
86+
timer.listen(Event::TimeOut);
87+
88+
// Move the timer into our global storage
89+
cortex_m::interrupt::free(|cs| *G_TIM.borrow(cs).borrow_mut() = Some(timer));
90+
91+
//enable TIM2 interrupt
92+
unsafe {
93+
cortex_m::peripheral::NVIC::unmask(Interrupt::TIM2);
94+
}
95+
96+
loop {
97+
wfi();
98+
}
99+
}

0 commit comments

Comments
 (0)