Skip to content

Commit 2ac85c8

Browse files
committed
Support external SYST clock source
Give users the option to configure SYST with an external clock source. By default, the clock source is the core, which keeps us backwards compatible. `_start` has a new input, but since users don't call that function directly, it doesn't seem like a problem to break that public API.
1 parent c305c18 commit 2ac85c8

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

rtic-monotonics/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top!
1010
### Changed
1111
- Panic if STM32 prescaler value would overflow
1212

13+
### Added
14+
15+
- Cortex-M `systick` can be configured with its external clock source
16+
1317
## v2.1.0 - 2025-06-22
1418

1519
### Changed

rtic-monotonics/src/systick.rs

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,26 @@
2828
//! }
2929
//! }
3030
//! ```
31+
//!
32+
//! By default, SysTick uses [`SystClkSource::Core`] as the clock source.
33+
//! To set the SysTick clock source, use `start_with_clock_source`:
34+
//!
35+
//! ```
36+
//! # use rtic_monotonics::systick::prelude::*;
37+
//! # systick_monotonic!(Mono, 1_000);
38+
//! use rtic_monotonics::systick::SystClkSource;
39+
//!
40+
//! fn init() {
41+
//! let core_peripherals = cortex_m::Peripherals::take().unwrap();
42+
//! // Start the monotonic using the cortex-m crate's Systick driver.
43+
//! // We tell it we have a 12MHz external clock source.
44+
//! Mono::start_with_clock_source(
45+
//! core_peripherals.SYST,
46+
//! 12_000_000,
47+
//! SystClkSource::External,
48+
//! );
49+
//! }
50+
//! ```
3151
3252
/// Common definitions and traits for using the systick monotonic
3353
pub mod prelude {
@@ -44,7 +64,7 @@ pub mod prelude {
4464
}
4565
}
4666

47-
pub use cortex_m::peripheral::SYST;
67+
pub use cortex_m::peripheral::{syst::SystClkSource, SYST};
4868

4969
use portable_atomic::Ordering;
5070
use rtic_time::timer_queue::TimerQueue;
@@ -72,7 +92,7 @@ impl SystickBackend {
7292
/// **Do not use this function directly.**
7393
///
7494
/// Use the prelude macros instead.
75-
pub fn _start(mut systick: SYST, sysclk: u32, timer_hz: u32) {
95+
pub fn _start(mut systick: SYST, sysclk: u32, timer_hz: u32, clk_source: SystClkSource) {
7696
assert!(
7797
sysclk.is_multiple_of(timer_hz),
7898
"timer_hz cannot evenly divide sysclk! Please adjust the timer or sysclk frequency."
@@ -83,7 +103,7 @@ impl SystickBackend {
83103
assert!(reload > 0);
84104

85105
systick.disable_counter();
86-
systick.set_clock_source(cortex_m::peripheral::syst::SystClkSource::Core);
106+
systick.set_clock_source(clk_source);
87107
systick.set_reload(reload);
88108
systick.enable_interrupt();
89109
systick.enable_counter();
@@ -172,16 +192,33 @@ macro_rules! systick_monotonic {
172192
/// Panics if it is impossible to achieve the desired monotonic tick rate based
173193
/// on the given `sysclk` parameter. If that happens, adjust the desired monotonic tick rate.
174194
///
175-
/// This method must be called only once.
195+
/// This method, or `start_with_clock_source`, must be called only once.
176196
pub fn start(systick: $crate::systick::SYST, sysclk: u32) {
197+
Self::start_with_clock_source(systick, sysclk, $crate::systick::SystClkSource::Core)
198+
}
199+
200+
/// Starts the `Monotonic` with your preferred SYST clock source.
201+
///
202+
/// The `sysclk` parameter is the speed at which SysTick runs at. This value should come from
203+
/// the clock generation function of the used HAL, depending on your `clk_source`.
204+
///
205+
/// Panics if it is impossible to achieve the desired monotonic tick rate based
206+
/// on the given `sysclk` parameter. If that happens, adjust the desired monotonic tick rate.
207+
///
208+
/// This method, or `start`, must be called only once.
209+
pub fn start_with_clock_source(
210+
systick: $crate::systick::SYST,
211+
sysclk: u32,
212+
clk_source: $crate::systick::SystClkSource,
213+
) {
177214
#[no_mangle]
178215
#[allow(non_snake_case)]
179216
unsafe extern "C" fn SysTick() {
180217
use $crate::TimerQueueBackend;
181218
$crate::systick::SystickBackend::timer_queue().on_monotonic_interrupt();
182219
}
183220

184-
$crate::systick::SystickBackend::_start(systick, sysclk, $tick_rate_hz);
221+
$crate::systick::SystickBackend::_start(systick, sysclk, $tick_rate_hz, clk_source);
185222
}
186223
}
187224

0 commit comments

Comments
 (0)