-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18 from decaday/feat/systick-time-driver
systick-time-driver support
- Loading branch information
Showing
10 changed files
with
401 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[target.thumbv6m-none-eabi] | ||
# probe-rs chip list | grep -i PY32 | ||
runner = 'probe-rs run --chip PY32F030x6' | ||
|
||
[build] | ||
target = "thumbv6m-none-eabi" | ||
|
||
[env] | ||
DEFMT_LOG = "info" | ||
|
||
# rustflags = ["-C", "link-arg=-Tlink.x"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
[package] | ||
name = "systick-time-driver-f030" | ||
version = "0.1.1" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
panic-halt = "1.0.0" | ||
cortex-m = { version = "0.7.7", features = [ | ||
"critical-section-single-core", | ||
"critical-section", | ||
] } | ||
cortex-m-rt = "0.7.3" | ||
cortex-m-semihosting = { version = "0.5" } | ||
panic-probe = { version = "0.3", features = ["print-defmt"] } | ||
|
||
embassy-sync = { version = "0.6.0", features = ["defmt"] } | ||
embassy-executor = { version = "0.6.1", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } | ||
embassy-time = { version = "0.3.2", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-1_000"] } | ||
|
||
embedded-io = { version = "0.6.0" } | ||
embedded-io-async = { version = "0.6.1" } | ||
|
||
py32-hal = { path = "../../", features = [ "time-driver-systick", "py32f030k28"]} | ||
|
||
defmt = "0.3" | ||
defmt-rtt = "0.4" | ||
|
||
# cargo build/run | ||
[profile.dev] | ||
codegen-units = 1 | ||
debug = 2 | ||
debug-assertions = true # <- | ||
incremental = false | ||
opt-level = 'z' # <- | ||
overflow-checks = true # <- | ||
|
||
# cargo build/run --release | ||
[profile.release] | ||
codegen-units = 1 | ||
debug = 2 | ||
debug-assertions = false # <- | ||
incremental = false | ||
lto = 'fat' | ||
opt-level = 3 # <- | ||
overflow-checks = false # <- | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
## Systick Time-Driver Demo | ||
|
||
Although we do not recommend using it and there are some shortcomings, it does work (after all, some chips lack sufficient multi-channel timers). | ||
|
||
Currently, the `systick-time-driver` implementation in `py32-hal` uses a retry loop. The reload value register (RVR) of the Systick timer is set to a fixed value, causing high-frequency interrupts. During these interrupts, it updates the tick count and checks whether any alarm has expired (since Systick lacks compare-capture functionality). | ||
|
||
The interrupt frequency of Systick matches the tick frequency configured for `embassy-time`. It is **not recommended** to use excessively high frequencies because `time-driver-systick` generates frequent interrupts, unlike `time-driver-timx`. Additionally, `time-driver-systick` updates the tick count and wakes up alarms in software, which takes longer. | ||
|
||
### Usage | ||
|
||
Enable the `time-driver-systick` feature. Then, before initializing `py32-hal`, add the following: | ||
|
||
```rust | ||
use cortex_m::Peripherals; | ||
let cp = Peripherals::take().unwrap(); | ||
let systick = cp.SYST; | ||
``` | ||
|
||
Pass the `systick` instance during initialization: | ||
|
||
```rust | ||
let p = py32_hal::init(Default::default(), systick); | ||
``` | ||
|
||
Complete code demo can be found in the same directory as this documentation. | ||
|
||
### Feature: `td-systick-multi-alarms` | ||
|
||
By default, only one alarm is provided (similar to a 2-channel timer). Enabling this feature provides three alarms (similar to a 4-channel timer). | ||
|
||
Of course, this will also increase the execution time of the interrupt handler. | ||
|
||
### More | ||
|
||
[SysTick time driver · Issue #786 · embassy-rs/embassy](https://github.com/embassy-rs/embassy/issues/786) | ||
|
||
Here are the key disadvantages of using **SysTick** as a time-driver: | ||
|
||
- **Clock Source Uncertainty**: SysTick supports two clock sources, but their speeds are not known at compile time, requiring vendor-specific runtime translation. | ||
- **Interrupt Limitation**: SysTick can only trigger an interrupt at zero, complicating setting alarms for specific points in the cycle. | ||
- **Dual-Core Challenges**: On dual-core devices like the RP2040, each core has an independent SysTick timer with no cross-access. | ||
- **Perturbation Issues**: Modifying the counter register while counting can perturb the overall tick count, affecting timing accuracy. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
fn main() { | ||
// `--nmagic` is required if memory section addresses are not aligned to 0x10000, | ||
// for example the FLASH and RAM sections in your `memory.x`. | ||
// See https://github.com/rust-embedded/cortex-m-quickstart/pull/95 | ||
println!("cargo:rustc-link-arg=--nmagic"); | ||
|
||
println!("cargo:rustc-link-arg=-Tlink.x"); | ||
|
||
println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#![no_std] | ||
#![no_main] | ||
#![feature(impl_trait_in_assoc_type)] | ||
|
||
use embassy_time::Timer; | ||
use py32_hal::gpio::{Level, Output, Speed}; | ||
use py32_hal::rcc::{Pll, PllSource, Sysclk}; | ||
use py32_hal::time::Hertz; | ||
use embassy_executor::Spawner; | ||
|
||
use cortex_m::Peripherals; | ||
use defmt::*; | ||
use {defmt_rtt as _, panic_halt as _}; | ||
|
||
|
||
#[embassy_executor::main] | ||
async fn main(_spawner: Spawner) { | ||
let cp = Peripherals::take().unwrap(); | ||
let systick = cp.SYST; | ||
|
||
let mut cfg: py32_hal::Config = Default::default(); | ||
cfg.rcc.hsi = Some(Hertz::mhz(24)); | ||
cfg.rcc.pll = Some(Pll { | ||
src: PllSource::HSI, | ||
}); | ||
cfg.rcc.sys = Sysclk::PLL; | ||
let p = py32_hal::init(cfg, systick); | ||
|
||
info!("Hello World!"); | ||
|
||
let mut led = Output::new(p.PB1, Level::High, Speed::Low); | ||
|
||
loop { | ||
info!("high"); | ||
led.set_high(); | ||
Timer::after_millis(1000).await; | ||
|
||
info!("low"); | ||
led.set_low(); | ||
Timer::after_millis(1000).await; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.