Skip to content

Commit 24f6f9f

Browse files
authored
Merge pull request #64 from stm32-rs/feature/pwr
Power controller refactoring
2 parents 45e1163 + 162ee40 commit 24f6f9f

File tree

11 files changed

+136
-21
lines changed

11 files changed

+136
-21
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/analog/adc.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ pub struct CalibrationFactor(pub u8);
116116
impl Adc {
117117
pub fn new(adc: ADC, rcc: &mut Rcc) -> Self {
118118
// Enable ADC clocks
119-
rcc.rb.apbenr2.modify(|_, w| w.adcen().set_bit());
119+
rcc.enable_adc();
120+
120121
adc.cr.modify(|_, w| w.advregen().set_bit());
121122

122123
Self {

src/crc.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,7 @@ pub trait CrcExt {
3131

3232
impl CrcExt for CRC {
3333
fn constrain(self, rcc: &mut Rcc) -> Config {
34-
// Enable power to CRC unit
35-
rcc.rb.ahbenr.modify(|_, w| w.crcen().set_bit());
36-
// Reset CRC unit
37-
rcc.rb.ahbrstr.modify(|_, w| w.crcrst().set_bit());
38-
rcc.rb.ahbrstr.modify(|_, w| w.crcrst().clear_bit());
34+
rcc.enable_crc();
3935

4036
// Default values
4137
Config {

src/flash/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ impl WriteErase for UnlockedFlash {
189189

190190
let mut chunks = aligned_data.chunks_exact(mem::size_of::<Self::NativeType>());
191191

192-
while let Some(exact_chunk) = chunks.next() {
192+
for exact_chunk in &mut chunks {
193193
// Write chunks
194194
let native = &[Self::NativeType::from_ne_bytes(
195195
exact_chunk.try_into().unwrap(),

src/gpio.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,30 +177,35 @@ macro_rules! gpio {
177177
_mode: PhantomData<MODE>,
178178
}
179179

180+
#[allow(clippy::from_over_into)]
180181
impl Into<$PXi<Input<PullDown>>> for $PXi<DefaultMode> {
181182
fn into(self) -> $PXi<Input<PullDown>> {
182183
self.into_pull_down_input()
183184
}
184185
}
185186

187+
#[allow(clippy::from_over_into)]
186188
impl Into<$PXi<Input<PullUp>>> for $PXi<DefaultMode> {
187189
fn into(self) -> $PXi<Input<PullUp>> {
188190
self.into_pull_up_input()
189191
}
190192
}
191193

194+
#[allow(clippy::from_over_into)]
192195
impl Into<$PXi<Input<Floating>>> for $PXi<DefaultMode> {
193196
fn into(self) -> $PXi<Input<Floating>> {
194197
self.into_floating_input()
195198
}
196199
}
197200

201+
#[allow(clippy::from_over_into)]
198202
impl Into<$PXi<Output<OpenDrain>>> for $PXi<DefaultMode> {
199203
fn into(self) -> $PXi<Output<OpenDrain>> {
200204
self.into_open_drain_output()
201205
}
202206
}
203207

208+
#[allow(clippy::from_over_into)]
204209
impl Into<$PXi<Output<PushPull>>> for $PXi<DefaultMode> {
205210
fn into(self) -> $PXi<Output<PushPull>> {
206211
self.into_push_pull_output()

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub mod exti;
5353
pub mod flash;
5454
pub mod gpio;
5555
pub mod i2c;
56+
pub mod power;
5657
pub mod prelude;
5758
pub mod rcc;
5859
#[cfg(any(feature = "stm32g041", feature = "stm32g081"))]

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: 14 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,20 @@ 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+
}
318+
319+
pub(crate) fn enable_adc(&self) {
320+
self.rb.apbenr2.modify(|_, w| w.adcen().set_bit());
321+
}
322+
323+
pub(crate) fn enable_crc(&self) {
324+
self.rb.ahbenr.modify(|_, w| w.crcen().set_bit());
325+
self.rb.ahbrstr.modify(|_, w| w.crcrst().set_bit());
326+
self.rb.ahbrstr.modify(|_, w| w.crcrst().clear_bit());
327+
}
327328
}
328329

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

src/serial/usart.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,6 @@ macro_rules! uart_shared {
326326
});
327327
}
328328
}
329-
330329
}
331330
}
332331

0 commit comments

Comments
 (0)