-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample-hal-sensor-button.rs
92 lines (72 loc) · 2.39 KB
/
example-hal-sensor-button.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
#![no_main]
#![no_std]
use cm::interrupt::Mutex;
use core::cell::RefCell;
use cortex_m as cm;
use cortex_m_rt::entry;
use hal::prelude::*;
use hal::stm32;
use hal::stm32::interrupt;
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
use stm32f1xx_hal as hal;
type ExtIntr = stm32::EXTI;
static G_EXTI: Mutex<RefCell<Option<ExtIntr>>> = Mutex::new(RefCell::new(None));
#[entry]
fn main() -> ! {
if let (Some(mut cp), Some(dp)) = (cm::Peripherals::take(), stm32::Peripherals::take()) {
cm::interrupt::free(|cs| {
let mut flash = dp.FLASH.constrain();
let mut rcc = dp.RCC.constrain();
rtt_init_print!();
let _clocks = rcc
.cfgr
.sysclk(8.mhz())
.pclk1(8.mhz())
.freeze(&mut flash.acr);
setup_interrupts(&mut cp);
let mut gpiod = dp.GPIOD.split(&mut rcc.apb2);
// PD1: GPIO floating input: one-channel touch sensor
gpiod.pd1.into_floating_input(&mut gpiod.crl);
let mut afio = dp.AFIO.constrain(&mut rcc.apb2);
// select PD1 as source input for line EXTI1
afio.exticr1
.exticr1()
.modify(|_, w| unsafe { w.exti1().bits(0b0011) });
// enable EXTI1 line and configure interrupt on rising edge
dp.EXTI.imr.modify(|_, w| w.mr1().set_bit());
// Note on levels:
// - use falling edge to detect pressed button
// - use rising edge to detect released button
dp.EXTI.ftsr.modify(|_, w| w.tr1().set_bit());
G_EXTI.borrow(cs).replace(Some(dp.EXTI));
});
}
loop {
rprintln!("idle loop");
delay(1000000);
}
}
fn delay(count: u32) {
for _ in 0..count {
cm::asm::nop();
}
}
fn setup_interrupts(cp: &mut cm::peripheral::Peripherals) {
let nvic = &mut cp.NVIC;
// Enable EXTI1, set prio 1, clear any pending IRQs
unsafe {
cm::peripheral::NVIC::unmask(stm32::Interrupt::EXTI1);
nvic.set_priority(stm32::Interrupt::EXTI1, 1);
}
cm::peripheral::NVIC::unpend(stm32::Interrupt::EXTI1);
}
#[interrupt]
fn EXTI1() {
cm::interrupt::free(|cs| {
rprintln!("Touch !");
if let Some(exti) = G_EXTI.borrow(cs).borrow().as_ref() {
exti.pr.modify(|_, w| w.pr1().set_bit());
}
});
}