Skip to content

Commit 835ece7

Browse files
committed
power controller refactoring
1 parent f06030c commit 835ece7

File tree

5 files changed

+111
-13
lines changed

5 files changed

+111
-13
lines changed

examples/rtic_low_power.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#![no_std]
2+
#![no_main]
3+
#![deny(warnings)]
4+
5+
extern crate cortex_m;
6+
extern crate cortex_m_rt as rt;
7+
extern crate panic_semihosting;
8+
extern crate rtic;
9+
extern crate stm32g0xx_hal as hal;
10+
11+
use hal::exti::Event;
12+
use hal::gpio::gpioa::PA5;
13+
use hal::gpio::{Output, PushPull, SignalEdge};
14+
use hal::power::{LowPowerMode, PowerMode};
15+
use hal::prelude::*;
16+
use hal::rcc::{self, Prescaler};
17+
use hal::stm32;
18+
use rtic::app;
19+
20+
#[app(device = hal::stm32, peripherals = true)]
21+
const APP: () = {
22+
struct Resources {
23+
exti: stm32::EXTI,
24+
led: PA5<Output<PushPull>>,
25+
}
26+
27+
#[init]
28+
fn init(mut ctx: init::Context) -> init::LateResources {
29+
let mut rcc = ctx.device.RCC.freeze(rcc::Config::hsi(Prescaler::Div16));
30+
let mut exti = ctx.device.EXTI;
31+
32+
let gpioa = ctx.device.GPIOA.split(&mut rcc);
33+
let gpioc = ctx.device.GPIOC.split(&mut rcc);
34+
35+
let led = gpioa.pa5.into_push_pull_output();
36+
let button = gpioc.pc13.listen(SignalEdge::Falling, &mut exti);
37+
38+
let mut power = ctx.device.PWR.constrain(&mut rcc);
39+
power.set_mode(PowerMode::LowPower(LowPowerMode::StopMode2));
40+
41+
if button.is_high().unwrap() {
42+
ctx.core.SCB.set_sleepdeep();
43+
}
44+
45+
init::LateResources { exti, led }
46+
}
47+
48+
#[task(binds = EXTI4_15, resources = [exti, led])]
49+
fn button_click(ctx: button_click::Context) {
50+
ctx.resources.led.toggle().unwrap();
51+
ctx.resources.exti.unpend(Event::GPIO13);
52+
}
53+
};

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ pub mod rcc;
5858
#[cfg(any(feature = "stm32g041", feature = "stm32g081"))]
5959
pub mod rng;
6060
pub mod rtc;
61+
pub mod power;
6162
pub mod serial;
6263
pub mod spi;
6364
pub mod time;

src/power.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//! Power control
2+
3+
use crate::{rcc::Rcc, stm32::PWR};
4+
5+
pub enum LowPowerMode {
6+
StopMode1 = 0b00,
7+
StopMode2 = 0b01,
8+
Standby = 0b11,
9+
}
10+
11+
pub enum PowerMode {
12+
Run,
13+
LowPower(LowPowerMode),
14+
}
15+
16+
pub struct Power {
17+
rb: PWR,
18+
}
19+
20+
impl Power {
21+
pub fn new(pwr: PWR, rcc: &mut Rcc) -> Self {
22+
rcc.enable_power_control();
23+
Self { rb: pwr }
24+
}
25+
26+
pub fn set_mode(&mut self, mode: PowerMode) {
27+
match mode {
28+
PowerMode::Run => {
29+
self.rb.cr1.modify(|_, w| w.lpr().clear_bit());
30+
while !self.rb.sr2.read().reglpf().bit_is_clear() {}
31+
}
32+
PowerMode::LowPower(sm) => {
33+
self.rb
34+
.cr1
35+
.modify(|_, w| unsafe { w.lpr().set_bit().lpms().bits(sm as u8) });
36+
while !self.rb.sr2.read().reglps().bit_is_set()
37+
|| !self.rb.sr2.read().reglpf().bit_is_set()
38+
{}
39+
}
40+
}
41+
}
42+
}
43+
44+
pub trait PowerExt {
45+
fn constrain(self, rcc: &mut Rcc) -> Power;
46+
}
47+
48+
impl PowerExt for PWR {
49+
fn constrain(self, rcc: &mut Rcc) -> Power {
50+
Power::new(self, rcc)
51+
}
52+
}

src/prelude.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub use crate::exti::ExtiExt as _;
2525
pub use crate::flash::FlashExt as _;
2626
pub use crate::gpio::GpioExt as _;
2727
pub use crate::i2c::I2cExt as _;
28+
pub use crate::power::PowerExt as _;
2829
pub use crate::rcc::LSCOExt as _;
2930
pub use crate::rcc::MCOExt as _;
3031
pub use crate::rcc::RccExt as _;

src/rcc/mod.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -192,19 +192,6 @@ impl Rcc {
192192
}
193193
}
194194

195-
pub fn enable_low_power_mode(&self) {
196-
assert!(self.clocks.sys_clk.0 <= 2_000_000);
197-
self.rb.apbenr1.modify(|_, w| w.pwren().set_bit());
198-
let pwr = unsafe { &(*PWR::ptr()) };
199-
pwr.cr1.modify(|_, w| w.lpr().set_bit());
200-
}
201-
202-
pub fn disable_low_power_mode(&self) {
203-
self.rb.apbenr1.modify(|_, w| w.pwren().set_bit());
204-
let pwr = unsafe { &(*PWR::ptr()) };
205-
pwr.cr1.modify(|_, w| w.lpr().clear_bit());
206-
}
207-
208195
fn config_pll(&self, pll_cfg: PllConfig) -> PLLClocks {
209196
assert!(pll_cfg.m > 0 && pll_cfg.m <= 8);
210197
assert!(pll_cfg.r > 1 && pll_cfg.r <= 8);
@@ -324,6 +311,10 @@ impl Rcc {
324311
.clear_bit()
325312
});
326313
}
314+
315+
pub(crate) fn enable_power_control(&self) {
316+
self.rb.apbenr1.modify(|_, w| w.pwren().set_bit());
317+
}
327318
}
328319

329320
/// Extension trait that constrains the `RCC` peripheral

0 commit comments

Comments
 (0)