Skip to content

Commit 24f18a4

Browse files
authored
Merge pull request #468 from Rutherther/rtc-frequency-fix
Fix RTC selection of frequency for LSI and HSE
2 parents 5dd7b0f + cd98a1f commit 24f18a4

File tree

2 files changed

+44
-50
lines changed

2 files changed

+44
-50
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3030
- Update `bxcan`, `heapless`, `mfrc522`, reenable `mpu9250` example [#513]
3131
- PWM timer auto reload value is now preloaded/buffered [#453]
3232
- Move from bors/manual merge to GH merge queue [#467]
33+
- `Rtc::restore_or_new`: adds restoring mechanism of running Rtc [#468]
34+
- `Rtc::select_frequency`: fix for LSI and HSE, where correct frequency was not selected [#468]
3335
- Replace UB code by a legitimate pointer access [#480]
3436
- Fix flash error flag clearing [#489]
3537
- Clarify README for windows users [#496]
@@ -59,6 +61,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
5961
[#453]: https://github.com/stm32-rs/stm32f1xx-hal/pull/453
6062
[#462]: https://github.com/stm32-rs/stm32f1xx-hal/pull/462
6163
[#467]: https://github.com/stm32-rs/stm32f1xx-hal/pull/467
64+
[#468]: https://github.com/stm32-rs/stm32f1xx-hal/pull/468
6265
[#479]: https://github.com/stm32-rs/stm32f1xx-hal/pull/479
6366
[#480]: https://github.com/stm32-rs/stm32f1xx-hal/pull/480
6467
[#483]: https://github.com/stm32-rs/stm32f1xx-hal/pull/483
@@ -81,6 +84,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
8184
[#528]: https://github.com/stm32-rs/stm32f1xx-hal/pull/528
8285
[#534]: https://github.com/stm32-rs/stm32f1xx-hal/pull/534
8386
[#536]: https://github.com/stm32-rs/stm32f1xx-hal/pull/536
87+
- Move from bors/manual merge to GH merge queue
88+
- Add tools/check.py python script for local check
89+
- Add changelog check on PRs
8490

8591
## [v0.10.0] - 2022-12-12
8692

src/rtc.rs

Lines changed: 38 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::time::{Hertz, Hz};
88

99
use core::convert::Infallible;
1010
use core::marker::PhantomData;
11+
use fugit::RateExtU32;
1112

1213
// The LSE runs at at 32 768 hertz unless an external clock is provided
1314
const LSE_HERTZ: Hertz = Hz(32_768);
@@ -43,6 +44,7 @@ pub enum RestoredOrNewRtc<CS> {
4344
*/
4445
pub struct Rtc<CS = RtcClkLse> {
4546
regs: RTC,
47+
frequency: Hertz,
4648
_clock_source: PhantomData<CS>,
4749
}
4850

@@ -63,22 +65,12 @@ impl Rtc<RtcClkLse> {
6365
[`restore_or_new`](Rtc::<RtcClkLse>::restore_or_new) instead.
6466
*/
6567
pub fn new(regs: RTC, bkp: &mut BackupDomain, rcc: &mut RCC) -> Self {
66-
let mut result = Rtc {
67-
regs,
68-
_clock_source: PhantomData,
69-
};
68+
let mut result = Self::init(regs);
7069

7170
Self::enable_rtc(bkp, rcc);
7271

7372
// Set the prescaler to make it count up once every second.
74-
let prl = LSE_HERTZ.raw() - 1;
75-
assert!(prl < 1 << 20);
76-
result.perform_write(|s| {
77-
s.regs.prlh().write(|w| unsafe { w.bits(prl >> 16) });
78-
s.regs
79-
.prll()
80-
.write(|w| unsafe { w.bits(prl as u16 as u32) });
81-
});
73+
result.select_frequency(1u32.Hz());
8274

8375
result
8476
}
@@ -105,10 +97,15 @@ impl Rtc<RtcClkLse> {
10597
if !Self::is_enabled() {
10698
RestoredOrNewRtc::New(Rtc::new(regs, bkp, rcc))
10799
} else {
108-
RestoredOrNewRtc::Restored(Rtc {
109-
regs,
110-
_clock_source: PhantomData,
111-
})
100+
RestoredOrNewRtc::Restored(Self::init(regs))
101+
}
102+
}
103+
104+
fn init(regs: RTC) -> Self {
105+
Self {
106+
regs,
107+
frequency: LSE_HERTZ,
108+
_clock_source: PhantomData,
112109
}
113110
}
114111

@@ -149,22 +146,12 @@ impl Rtc<RtcClkLsi> {
149146
[`restore_or_new_lsi`](Rtc::<RtcClkLsi>::restore_or_new_lsi) instead.
150147
*/
151148
pub fn new_lsi(regs: RTC, bkp: &mut BackupDomain) -> Self {
152-
let mut result = Rtc {
153-
regs,
154-
_clock_source: PhantomData,
155-
};
149+
let mut result = Self::init(regs);
156150

157151
Self::enable_rtc(bkp);
158152

159153
// Set the prescaler to make it count up once every second.
160-
let prl = LSI_HERTZ.raw() - 1;
161-
assert!(prl < 1 << 20);
162-
result.perform_write(|s| {
163-
s.regs.prlh().write(|w| unsafe { w.bits(prl >> 16) });
164-
s.regs
165-
.prll()
166-
.write(|w| unsafe { w.bits(prl as u16 as u32) });
167-
});
154+
result.select_frequency(1u32.Hz());
168155

169156
result
170157
}
@@ -175,10 +162,15 @@ impl Rtc<RtcClkLsi> {
175162
if !Rtc::<RtcClkLsi>::is_enabled() {
176163
RestoredOrNewRtc::New(Rtc::new_lsi(regs, bkp))
177164
} else {
178-
RestoredOrNewRtc::Restored(Rtc {
179-
regs,
180-
_clock_source: PhantomData,
181-
})
165+
RestoredOrNewRtc::Restored(Self::init(regs))
166+
}
167+
}
168+
169+
fn init(regs: RTC) -> Self {
170+
Self {
171+
regs,
172+
frequency: LSI_HERTZ,
173+
_clock_source: PhantomData,
182174
}
183175
}
184176

@@ -224,22 +216,12 @@ impl Rtc<RtcClkHseDiv128> {
224216
[`restore_or_new_hse`](Rtc::<RtcClkHseDiv128>::restore_or_new_hse) instead.
225217
*/
226218
pub fn new_hse(regs: RTC, bkp: &mut BackupDomain, hse: Hertz) -> Self {
227-
let mut result = Rtc {
228-
regs,
229-
_clock_source: PhantomData,
230-
};
219+
let mut result = Self::init(regs, hse);
231220

232221
Self::enable_rtc(bkp);
233222

234223
// Set the prescaler to make it count up once every second.
235-
let prl = hse.raw() / 128 - 1;
236-
assert!(prl < 1 << 20);
237-
result.perform_write(|s| {
238-
s.regs.prlh().write(|w| unsafe { w.bits(prl >> 16) });
239-
s.regs
240-
.prll()
241-
.write(|w| unsafe { w.bits(prl as u16 as u32) });
242-
});
224+
result.select_frequency(1u32.Hz());
243225

244226
result
245227
}
@@ -254,10 +236,15 @@ impl Rtc<RtcClkHseDiv128> {
254236
if !Self::is_enabled() {
255237
RestoredOrNewRtc::New(Rtc::new_hse(regs, bkp, hse))
256238
} else {
257-
RestoredOrNewRtc::Restored(Rtc {
258-
regs,
259-
_clock_source: PhantomData,
260-
})
239+
RestoredOrNewRtc::Restored(Self::init(regs, hse))
240+
}
241+
}
242+
243+
fn init(regs: RTC, hse: Hertz) -> Self {
244+
Self {
245+
regs,
246+
frequency: hse / 128,
247+
_clock_source: PhantomData,
261248
}
262249
}
263250

@@ -290,9 +277,10 @@ impl<CS> Rtc<CS> {
290277
pub fn select_frequency(&mut self, frequency: Hertz) {
291278
// The manual says that the zero value for the prescaler is not recommended, thus the
292279
// minimum division factor is 2 (prescaler + 1)
293-
assert!(frequency <= LSE_HERTZ / 2);
280+
assert!(frequency <= self.frequency / 2);
294281

295-
let prescaler = LSE_HERTZ / frequency - 1;
282+
let prescaler = self.frequency / frequency - 1;
283+
assert!(prescaler < 1 << 20);
296284
self.perform_write(|s| {
297285
s.regs.prlh().write(|w| unsafe { w.bits(prescaler >> 16) });
298286
s.regs

0 commit comments

Comments
 (0)