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

sleep mode

parent 547089f2
No related branches found
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