Skip to content

Commit 6ee708a

Browse files
committed
Added PWR module for power control. This was required for RTC. The RTC now 'works' but I think the date formatting is wrong, I set a time of 19 hours and when I get time its 7 (12h difference).
1 parent a2eb8af commit 6ee708a

File tree

5 files changed

+128
-8
lines changed

5 files changed

+128
-8
lines changed

examples/rtc.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use hal::stm32l4::stm32l4x2;
2020
use hal::delay::Delay;
2121
use hal::rtc::Rtc;
2222
use hal::rtc::Time;
23+
use hal::pwr::Pwr;
2324
use hal::datetime::*;
2425
use rt::ExceptionFrame;
2526

@@ -47,8 +48,8 @@ fn main() -> ! {
4748
// .pclk1(32.mhz())
4849
// .freeze(&mut flash.acr);
4950
let mut timer = Delay::new(cp.SYST, clocks);
50-
51-
let rtc = Rtc::init(dp.RTC, &mut rcc.bdcr);
51+
let mut pwr = Pwr::pwr(&mut rcc.apb1r1);
52+
let rtc = Rtc::rtc(dp.RTC, &mut rcc.apb1r1, &mut rcc.bdcr, &mut pwr.cr1);
5253
let time = Time::new(0, 0, 19, false);
5354
rtc.set_time(&time);
5455

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub mod timer;
2424
pub mod spi;
2525
pub mod datetime;
2626
pub mod rtc;
27+
pub mod pwr;
2728

2829

2930
#[cfg(test)]

src/pwr.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// TODO impl power module so we enable backup domain for rtc etc
2+
// apb1r1.enr().modify(|_, w| w.pwren().set_bit());
3+
4+
use rcc::{APB1R1};
5+
use stm32l4::stm32l4x2::{pwr, PWR};
6+
7+
8+
pub struct Pwr {
9+
pub cr1: CR1,
10+
pub cr2: CR2,
11+
pub cr3: CR3,
12+
pub cr4: CR4,
13+
}
14+
15+
impl Pwr {
16+
pub fn pwr(apb1r1: &mut APB1R1) -> Self {
17+
apb1r1.enr().modify(|_, w| w.pwren().set_bit());
18+
19+
Self {
20+
cr1: CR1 { _0: () },
21+
cr2: CR2 { _0: () },
22+
cr3: CR3 { _0: () },
23+
cr4: CR4 { _0: () },
24+
}
25+
}
26+
}
27+
28+
/// CR1
29+
pub struct CR1 {
30+
_0: (),
31+
}
32+
33+
impl CR1 {
34+
// TODO remove `allow`
35+
#[allow(dead_code)]
36+
pub(crate) fn reg(&mut self) -> &pwr::CR1 {
37+
// NOTE(unsafe) this proxy grants exclusive access to this register
38+
unsafe { &(*PWR::ptr()).cr1 }
39+
}
40+
}
41+
/// CR2
42+
pub struct CR2 {
43+
_0: (),
44+
}
45+
46+
impl CR2 {
47+
// TODO remove `allow`
48+
#[allow(dead_code)]
49+
pub(crate) fn reg(&mut self) -> &pwr::CR2 {
50+
// NOTE(unsafe) this proxy grants exclusive access to this register
51+
unsafe { &(*PWR::ptr()).cr2 }
52+
}
53+
}
54+
/// CR3
55+
pub struct CR3 {
56+
_0: (),
57+
}
58+
59+
impl CR3 {
60+
// TODO remove `allow`
61+
#[allow(dead_code)]
62+
pub(crate) fn reg(&mut self) -> &pwr::CR3 {
63+
// NOTE(unsafe) this proxy grants exclusive access to this register
64+
unsafe { &(*PWR::ptr()).cr3 }
65+
}
66+
}
67+
/// CR4
68+
pub struct CR4 {
69+
_0: (),
70+
}
71+
72+
impl CR4 {
73+
// TODO remove `allow`
74+
#[allow(dead_code)]
75+
pub(crate) fn reg(&mut self) -> &pwr::CR4 {
76+
// NOTE(unsafe) this proxy grants exclusive access to this register
77+
unsafe { &(*PWR::ptr()).cr4 }
78+
}
79+
}

src/rcc.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ impl RccExt for RCC {
2424
apb1r2: APB1R2 { _0: () },
2525
apb2: APB2 { _0: () },
2626
bdcr: BDCR { _0: () },
27+
csr: CSR { _0: () },
2728
cfgr: CFGR {
2829
hclk: None,
2930
pclk1: None,
@@ -48,12 +49,29 @@ pub struct Rcc {
4849
pub apb1r2: APB1R2,
4950
/// Advanced Peripheral Bus 2 (APB2) registers
5051
pub apb2: APB2,
52+
/// Clock configuration register
5153
pub cfgr: CFGR,
5254
/// Backup domain control register
53-
pub bdcr : BDCR,
55+
pub bdcr: BDCR,
56+
/// Control/Status Register
57+
pub csr: CSR,
5458
}
5559

56-
// AMBA High-performance Bus (AHB1) registers
60+
// CSR Control/Status Register
61+
pub struct CSR {
62+
_0: (),
63+
}
64+
65+
impl CSR {
66+
// TODO remove `allow`
67+
#[allow(dead_code)]
68+
pub(crate) fn csr(&mut self) -> &rcc::CSR {
69+
// NOTE(unsafe) this proxy grants exclusive access to this register
70+
unsafe { &(*RCC::ptr()).csr }
71+
}
72+
}
73+
74+
// BDCR Backup domain control register registers
5775
pub struct BDCR {
5876
_0: (),
5977
}
@@ -377,6 +395,13 @@ impl CFGR {
377395

378396
while rcc.cfgr.read().sws().bits() != sysclk_src_bits {}
379397

398+
// Turn on the internal 32khz lsi oscillator
399+
rcc.csr.modify(|_, w| {
400+
w.lsion().set_bit()
401+
});
402+
// Wait until LSI is running
403+
while rcc.csr.read().lsirdy().bit_is_clear() {}
404+
380405

381406
Clocks {
382407
hclk: Hertz(hclk),

src/rtc.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/// RTC peripheral abstraction
22
33
use datetime::*;
4-
use rcc::{BDCR};
4+
use rcc::{BDCR, APB1R1};
5+
use pwr;
56
use stm32l4::stm32l4x2::{RTC};
67

78
#[derive(Clone,Copy,Debug)]
@@ -29,7 +30,16 @@ pub struct Rtc {
2930
}
3031

3132
impl Rtc {
32-
pub fn init(rtc: RTC, bdcr: &mut BDCR) -> Self {
33+
pub fn rtc(rtc: RTC, apb1r1: &mut APB1R1, bdcr: &mut BDCR, pwrcr1: &mut pwr::CR1) -> Self {
34+
// enable peripheral clock for communication
35+
apb1r1.enr().modify(|_, w| w.rtcapben().set_bit());
36+
pwrcr1.reg().read(); // read to allow the pwr clock to enable
37+
38+
pwrcr1.reg().modify(|_, w| w.dbp().set_bit());
39+
while pwrcr1.reg().read().dbp().bit_is_clear() {}
40+
41+
bdcr.enr().modify(|_, w| { w.bdrst().set_bit() }); // reset
42+
3343
bdcr.enr().modify(|_, w| unsafe {
3444
w.rtcsel()
3545
/*
@@ -41,8 +51,11 @@ impl Rtc {
4151
.bits(0b10)
4252
.rtcen()
4353
.set_bit()
54+
.bdrst() // reset required for clock source change
55+
.clear_bit()
4456
});
4557

58+
4659
write_protection(&rtc, false);
4760
{
4861
init_mode(&rtc, true);
@@ -151,8 +164,9 @@ fn write_protection(rtc: &RTC, enable: bool){
151164
fn init_mode(rtc: &RTC, enabled: bool) {
152165
if enabled {
153166
let isr = rtc.isr.read();
154-
if isr.initf().bit_is_clear() {
155-
rtc.isr.write(|w| unsafe { w.bits(0xFFFFFFFF) }); // Sets init mode
167+
if isr.initf().bit_is_clear() { // are we already in init mode?
168+
rtc.isr.write(|w| { w.init().set_bit() });
169+
// rtc.isr.write(|w| unsafe { w.bits(0xFFFFFFFF) }); // Sets init mode
156170
while rtc.isr.read().initf().bit_is_clear() {} // wait to return to init state
157171
}
158172
} else {

0 commit comments

Comments
 (0)