Skip to content

Commit fddfca6

Browse files
committed
Add blinking_led_with_interrupts example
1 parent 53e64ae commit fddfca6

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#![no_std]
2+
#![no_main]
3+
#![feature(alloc_error_handler)]
4+
5+
extern crate alloc_cortex_m;
6+
extern crate cortex_m;
7+
extern crate cortex_m_rt as rt;
8+
extern crate cortex_m_semihosting;
9+
extern crate stm32f7;
10+
extern crate stm32f7_discovery;
11+
12+
use alloc_cortex_m::CortexMHeap;
13+
use core::alloc::Layout as AllocLayout;
14+
use core::panic::PanicInfo;
15+
use rt::{entry, exception};
16+
use stm32f7::stm32f7x6::{CorePeripherals, Peripherals};
17+
use stm32f7_discovery::{
18+
gpio::{GpioPort, OutputPin},
19+
init,
20+
system_clock::{self, Hz},
21+
interrupts::{self, InterruptRequest, Priority},
22+
};
23+
24+
const HEAP_SIZE: usize = 50 * 1024; // in bytes
25+
26+
#[entry]
27+
fn main() -> ! {
28+
let core_peripherals = CorePeripherals::take().unwrap();
29+
let mut systick = core_peripherals.SYST;
30+
let mut nvic = core_peripherals.NVIC;
31+
32+
let peripherals = Peripherals::take().unwrap();
33+
let mut rcc = peripherals.RCC;
34+
let mut pwr = peripherals.PWR;
35+
let mut flash = peripherals.FLASH;
36+
let mut tim6 = peripherals.TIM6;
37+
let mut nvic_stir = peripherals.NVIC_STIR;
38+
39+
init::init_system_clock_216mhz(&mut rcc, &mut pwr, &mut flash);
40+
init::enable_gpio_ports(&mut rcc);
41+
42+
let gpio_a = GpioPort::new_a(&peripherals.GPIOA);
43+
let gpio_b = GpioPort::new_b(&peripherals.GPIOB);
44+
let gpio_c = GpioPort::new(&peripherals.GPIOC);
45+
let gpio_d = GpioPort::new(&peripherals.GPIOD);
46+
let gpio_e = GpioPort::new(&peripherals.GPIOE);
47+
let gpio_f = GpioPort::new(&peripherals.GPIOF);
48+
let gpio_g = GpioPort::new(&peripherals.GPIOG);
49+
let gpio_h = GpioPort::new(&peripherals.GPIOH);
50+
let gpio_i = GpioPort::new(&peripherals.GPIOI);
51+
let gpio_j = GpioPort::new(&peripherals.GPIOJ);
52+
let gpio_k = GpioPort::new(&peripherals.GPIOK);
53+
let mut pins = init::pins(
54+
gpio_a, gpio_b, gpio_c, gpio_d, gpio_e, gpio_f, gpio_g, gpio_h, gpio_i, gpio_j, gpio_k,
55+
);
56+
57+
// configure the systick timer 20Hz (20 ticks per second)
58+
init::init_systick(Hz(20), &mut systick, &rcc);
59+
systick.enable_interrupt();
60+
61+
// turn led on
62+
pins.led.set(true);
63+
64+
// enable timers
65+
rcc.apb1enr.modify(|_, w| w.tim6en().enabled());
66+
67+
// configure timer
68+
// clear update event
69+
tim6.sr.modify(|_, w| w.uif().clear_bit());
70+
71+
// setup timing
72+
tim6.psc.modify(|_, w| unsafe { w.psc().bits(42000) });
73+
tim6.arr.modify(|_, w| unsafe { w.arr().bits(3000) });
74+
75+
// enable interrupt
76+
tim6.dier.modify(|_, w| w.uie().set_bit());
77+
// start the timer counter
78+
tim6.cr1.modify(|_, w| w.cen().set_bit());
79+
80+
// The interrupt module needs an allocator for its dynamic interrupt table.
81+
unsafe { ALLOCATOR.init(rt::heap_start() as usize, HEAP_SIZE) }
82+
83+
interrupts::scope(
84+
&mut nvic,
85+
&mut nvic_stir,
86+
|_| {},
87+
|interrupt_table| {
88+
let _ = interrupt_table.register(InterruptRequest::TIM6_DAC, Priority::P1, || {
89+
pins.led.toggle();
90+
let tim = &mut tim6;
91+
// make sure the interrupt doesn't just restart again by clearing the flag
92+
tim.sr.modify(|_, w| w.uif().clear_bit());
93+
});
94+
95+
loop {}
96+
},
97+
)
98+
}
99+
100+
#[global_allocator]
101+
static ALLOCATOR: CortexMHeap = CortexMHeap::empty();
102+
103+
#[exception]
104+
fn SysTick() {
105+
system_clock::tick();
106+
}
107+
108+
// define what happens in an Out Of Memory (OOM) condition
109+
#[alloc_error_handler]
110+
fn rust_oom(_: AllocLayout) -> ! {
111+
loop {}
112+
}
113+
114+
#[panic_handler]
115+
fn panic(info: &PanicInfo) -> ! {
116+
use core::fmt::Write;
117+
use cortex_m::asm;
118+
use cortex_m_semihosting::hio;
119+
120+
if let Ok(mut hstdout) = hio::hstdout() {
121+
let _ = writeln!(hstdout, "{}", info);
122+
}
123+
124+
// OK to fire a breakpoint here because we know the microcontroller is connected to a debugger
125+
asm::bkpt();
126+
127+
loop {}
128+
}

0 commit comments

Comments
 (0)