Skip to content
Snippets Groups Projects
Commit 0db730af authored by Per's avatar Per
Browse files

sleep mode

parent 547089f2
Branches
No related tags found
No related merge requests found
//! Sleep mode example
#![no_main]
#![no_std]
extern crate cortex_m;
#[macro_use(interrupt)]
extern crate stm32f40x;
use stm32f40x::Interrupt;
#[macro_use(entry, exception)]
extern crate cortex_m_rt as rt;
extern crate panic_abort;
use cortex_m::asm;
use rt::ExceptionFrame;
use cortex_m::peripheral::Peripherals;
// set the MCU in debug sleepdeep mode on WFI/WFE
// debugging is possible even if sleeping
fn dbg_enable() {
let dbg = unsafe { &*stm32f40x::DBG::ptr() };
dbg.dbgmcu_cr.modify(|_, w| {
w.dbg_sleep()
.set_bit()
.dbg_stop()
.set_bit()
.dbg_standby()
.set_bit()
.trace_ioen()
.set_bit()
});
}
// set the MCU in true sleepdeep mode on WFI/WFE
// debugging is disabled (until re-enabled)
fn dbg_disable() {
let dbg = unsafe { &*stm32f40x::DBG::ptr() };
dbg.dbgmcu_cr.modify(|_, w| {
w.dbg_sleep()
.clear_bit()
.dbg_stop()
.clear_bit()
.dbg_standby()
.clear_bit()
.trace_ioen()
.clear_bit()
});
}
fn wait_cycles(p: &Peripherals, nr_cycles: u32) {
let t = p.DWT.cyccnt.read().wrapping_add(nr_cycles);
while (p.DWT.cyccnt.read().wrapping_sub(t) as i32) < 0 {}
}
fn blink(r: &stm32f40x::Peripherals, p: &Peripherals) {
r.RCC.ahb1enr.modify(|_, w| w.gpioaen().set_bit());
r.GPIOA.moder.modify(|_, w| w.moder5().output_mode());
for _ in 0..10 {
r.GPIOA.bsrr.write(|w| w.br5().set_bit());
for _ in 0..1000 {}
// wait_cycles(p, 1000_000);
r.GPIOA.bsrr.write(|w| w.bs5().set_bit());
for _ in 0..1000 {}
// wait_cycles(p, 1000_000);
}
r.GPIOA.moder.modify(|_, w| w.moder5().input_mode());
}
// the program entry point is ...
entry!(main);
// ... this never ending function
fn main() -> ! {
let r = stm32f40x::Peripherals::take().unwrap();
let mut p = Peripherals::take().unwrap();
// enable the EXTI1 interrupt
p.NVIC.enable(Interrupt::EXTI1);
// enable gpioa (input mode on reset)
r.RCC.ahb1enr.modify(|_, w| w.gpioaen().set_bit());
// enbable masking of EXTI line 1
r.EXTI.imr.modify(|_, w| w.mr1().set_bit());
// trigger on falling edge
r.EXTI.ftsr.modify(|_, w| w.tr1().set_bit());
asm::bkpt();
blink(&r, &p);
// p.NVIC.set_pending(Interrupt::EXTI1);
dbg_disable();
asm::wfi();
dbg_enable();
// asm::bkpt();
loop {}
}
// bind the EXTI1 handler
interrupt!(EXTI1, exti1);
// unsafe version where we access GPIOA through the (raw) pointer
fn blink2() {
let GPIOA = unsafe { &*stm32f40x::GPIOA::ptr() };
GPIOA.moder.modify(|_, w| w.moder5().output_mode());
for _ in 0..10 {
GPIOA.bsrr.write(|w| w.br5().set_bit());
for _ in 0..1000 {}
// wait_cycles(p, 1000_000);
GPIOA.bsrr.write(|w| w.bs5().set_bit());
for _ in 0..1000 {}
// wait_cycles(p, 1000_000);
}
GPIOA.moder.modify(|_, w| w.moder5().input_mode());
}
use cortex_m::interrupt::Nr;
// the exti1 interrupt implementation
fn exti1() {
// dbg_enable();
// asm::bkpt();
blink2();
// // let's try to "fake" access to GPIOA
// // let g = stm32f40x::GPIOA {
// // _marker: core::marker::PhantomData, <- the field is private, so we cannot
// // };
// asm::bkpt();
// clear pending state
let exti = unsafe { &*stm32f40x::EXTI::ptr() };
exti.imr.modify(|_, w| w.mr1().clear_bit());
exti.pr.reset();
let nvic = unsafe { &*cortex_m::peripheral::NVIC::ptr() };
let nr = Interrupt::EXTI1.nr();
unsafe { nvic.icpr[usize::from(nr / 32)].write(1 << (nr % 32)) };
unsafe { nvic.icer[usize::from(nr / 32)].write(1 << (nr % 32)) };
}
// define the hard fault handler
exception!(HardFault, hard_fault);
fn hard_fault(_ef: &ExceptionFrame) -> ! {
asm::bkpt();
loop {}
}
// define the default exception handler
exception!(*, default_handler);
fn default_handler(_irqn: i16) {
asm::bkpt();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment