Skip to content

Commit d04e034

Browse files
bors[bot]barafaelAfoHT
authored
Merge #37
37: Add stm32l0-monotonic example for RTIC v1.0 r=AfoHT a=barafael This example was ported from rtic_v0.5/stm32l0_monotonic. I cannot test as the only L0 chip I have is one without TIM6 which is needed. I have one coming in the mail though :) Co-authored-by: Rafael Bachmann <[email protected]> Co-authored-by: Henrik Tjäder <[email protected]>
2 parents a0694b8 + 69c582d commit d04e034

File tree

8 files changed

+251
-2
lines changed

8 files changed

+251
-2
lines changed

.github/dependabot.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ updates:
7575
schedule:
7676
interval: "weekly"
7777
rebase-strategy: "disabled"
78+
- package-ecosystem: "cargo"
79+
directory: "/rtic_v1/stm32l0_monotonic"
80+
schedule:
81+
interval: "weekly"
82+
rebase-strategy: "disabled"
7883
- package-ecosystem: "cargo"
7984
directory: "/rtic_v1/stm32l4_heartbeat"
8085
schedule:

rtic_v0.5/stm32l0_monotonic/src/main.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ use core::fmt::Write;
77

88
use panic_halt as _;
99
use rtic::app;
10-
use stm32l0xx_hal::prelude::*;
11-
use stm32l0xx_hal::{pac, rcc::Config, serial};
10+
use stm32l0xx_hal::{pac, prelude::*, rcc::Config, serial};
1211

1312
use crate::monotonic_stm32l0::{Duration, Instant, Tim6Monotonic, U16Ext};
1413

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
[target.thumbv7m-none-eabi]
2+
# uncomment this to make `cargo run` execute programs on QEMU
3+
# runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"
4+
5+
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
6+
# uncomment ONE of these three option to make `cargo run` start a GDB session
7+
# which option to pick depends on your system
8+
# runner = "arm-none-eabi-gdb -q -x jlink.gdb"
9+
# runner = "arm-none-eabi-gdb -q -x openocd.gdb"
10+
# runner = "gdb-multiarch -q -x openocd.gdb"
11+
# runner = "gdb -q -x openocd.gdb"
12+
13+
rustflags = [
14+
# LLD (shipped with the Rust toolchain) is used as the default linker
15+
"-C", "link-arg=-Tlink.x",
16+
17+
# if you run into problems with LLD switch to the GNU linker by commenting out
18+
# this line
19+
# "-C", "linker=arm-none-eabi-ld",
20+
21+
# if you need to link to pre-compiled C libraries provided by a C toolchain
22+
# use GCC as the linker by commenting out both lines above and then
23+
# uncommenting the three lines below
24+
# "-C", "linker=arm-none-eabi-gcc",
25+
# "-C", "link-arg=-Wl,-Tlink.x",
26+
# "-C", "link-arg=-nostartfiles",
27+
28+
# uncomment for unchecked wrapping arithmetics also in dev mode
29+
# "-Z", "force-overflow-checks=off",
30+
]
31+
32+
[build]
33+
# Pick ONE of these compilation targets
34+
target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
35+
# target = "thumbv7m-none-eabi" # Cortex-M3
36+
# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU)
37+
# target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Refer to https://github.com/probe-rs/cargo-embed/blob/master/src/config/default.toml
2+
# for the comprehensive list of options
3+
4+
[default.general]
5+
chip = "STM32L071"
6+
7+
[default.rtt]
8+
enabled = true
9+
show_timestamps = true
10+
11+
[default.gdb]
12+
# Whether or not a GDB server should be opened after flashing.
13+
# This is exclusive and cannot be used with RTT at the moment.
14+
enabled = false
15+
# The connection string in host:port format wher the GDB server will open a socket.
16+
# gdb_connection_string
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/target
2+
**/*.rs.bk
3+
Cargo.lock
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[package]
2+
name = "stm32l0_monotonic"
3+
categories = ["embedded", "no-std"]
4+
authors = ["Danilo Bargen <[email protected]>"]
5+
description = "Example Monotonic trait"
6+
keywords = ["arm", "cortex-m"]
7+
license = "MIT OR Apache-2.0"
8+
version = "0.1.0"
9+
edition = "2021"
10+
11+
[dependencies]
12+
cortex-m-rtic = "1.0.0"
13+
systick-monotonic = "1.0.1"
14+
panic-rtt-target = { version = "0.1.2", features = ["cortex-m"] }
15+
rtt-target = { version = "0.3.1", features = ["cortex-m"] }
16+
stm32l0xx-hal = { version = "0.9.0", features = ["rt", "mcu-STM32L031K6Tx"] }
17+
18+
# this lets you use `cargo fix`!
19+
[[bin]]
20+
name = "stm32l0_monotonic"
21+
test = false
22+
bench = false
23+
24+
[profile.dev]
25+
opt-level = 1
26+
codegen-units = 16
27+
debug = true
28+
lto = false
29+
30+
[profile.release]
31+
opt-level = "s" # optimize for size
32+
codegen-units = 1 # better optimizations
33+
debug = true # symbols are nice and they don't increase the size on Flash
34+
lto = true # better optimizations
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# STM32L0 Monotonic
2+
3+
In this example we show the use of a custom `rtic::Monotonic` implementation
4+
which uses a 16 bit timer of the `STM32L0` MCU.
5+
6+
## Flashing and running
7+
8+
Flashing with a standard STLink v2 is easy with `cargo-embed`:
9+
10+
```shell
11+
$ cargo install cargo-embed
12+
$ cargo embed --release
13+
```
14+
15+
Please review the `.embed.toml` file to change your target IC among other options.
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#![no_main]
2+
#![no_std]
3+
4+
use core::fmt::Write;
5+
6+
use panic_rtt_target as _;
7+
use rtt_target::{rprintln, rtt_init_print};
8+
9+
use rtic::app;
10+
use stm32l0xx_hal::{pac, prelude::*, rcc::Config, serial};
11+
use systick_monotonic::{
12+
fugit::{ExtU32, MillisDurationU64},
13+
Systick,
14+
};
15+
16+
const INTERVAL_MS: u32 = 500;
17+
18+
#[app(
19+
device = stm32l0xx_hal::pac,
20+
peripherals = true,
21+
dispatchers = [SPI1],
22+
)]
23+
mod app {
24+
use super::*;
25+
26+
// Setting this monotonic as the default
27+
// enables the shorthand fizzbuzz::spawn_after
28+
// without having to specify `Mono` as fizzbuzz::Mono::spawn_after(
29+
#[monotonic(binds = SysTick, default = true)]
30+
type Tonic = Systick<1000>;
31+
32+
#[local]
33+
struct Local {
34+
/// Serial debug output
35+
serial: serial::Serial<pac::USART2>,
36+
37+
/// Timer interval
38+
interval: MillisDurationU64,
39+
40+
/// Counter
41+
counter: usize,
42+
}
43+
44+
#[shared]
45+
struct Shared {}
46+
47+
#[init]
48+
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
49+
// Get peripherals
50+
let dp: pac::Peripherals = cx.device;
51+
52+
// Clock configuration. Use HSI at 16 MHz.
53+
let mut rcc = dp.RCC.freeze(Config::hsi16());
54+
55+
rtt_init_print!();
56+
rprintln!("RTT init");
57+
58+
// GPIO
59+
let gpiob = dp.GPIOB.split(&mut rcc);
60+
61+
// Initialize serial port(s)
62+
let mut serial = serial::Serial::usart2(
63+
dp.USART2,
64+
gpiob.pb6.into_floating_input(),
65+
gpiob.pb7.into_floating_input(),
66+
serial::Config {
67+
baudrate: 57_600.Bd(),
68+
wordlength: serial::WordLength::DataBits8,
69+
parity: serial::Parity::ParityNone,
70+
stopbits: serial::StopBits::STOP1,
71+
},
72+
&mut rcc,
73+
)
74+
.unwrap();
75+
76+
// Initialize the timer
77+
writeln!(serial, "Initialize monotonic timer using SysTick at 1kHz").unwrap();
78+
79+
let mono = Systick::new(cx.core.SYST, 16_000_000);
80+
81+
let interval: MillisDurationU64 = INTERVAL_MS.millis().into();
82+
83+
writeln!(
84+
serial,
85+
"Schedule task every {} ms / {} ticks",
86+
interval,
87+
interval.ticks(),
88+
)
89+
.unwrap();
90+
91+
// Spawn task "fizzbuzz"
92+
let _ = fizzbuzz::spawn();
93+
94+
writeln!(serial, "== Init done ==").unwrap();
95+
96+
let local = Local {
97+
serial,
98+
interval,
99+
counter: 1,
100+
};
101+
102+
(Shared {}, local, init::Monotonics(mono))
103+
}
104+
105+
#[task(local = [serial, interval, counter])]
106+
fn fizzbuzz(cx: fizzbuzz::Context) {
107+
rprintln!("fizzbuzz!");
108+
// Access resources
109+
let serial = cx.local.serial;
110+
let now = monotonics::now();
111+
let counter = cx.local.counter;
112+
let interval = cx.local.interval;
113+
114+
// Fancy fizzbuzz implementation
115+
match (*counter % 3 == 0, *counter % 5 == 0) {
116+
(true, true) => {
117+
rprintln!("fizzbuzz (now={:05})", now);
118+
writeln!(serial, "fizzbuzz (now={:05})", now).unwrap();
119+
}
120+
(true, false) => {
121+
rprintln!(" fizz (now={:05})", now);
122+
writeln!(serial, " fizz (now={:05})", now).unwrap();
123+
}
124+
(false, true) => {
125+
rprintln!(" buzz (now={:05})", now);
126+
writeln!(serial, " buzz (now={:05})", now).unwrap();
127+
}
128+
_ => {
129+
rprintln!("{:08} (now={:05})", *counter, now);
130+
writeln!(serial, "{:08} (now={:05})", *counter, now).unwrap();
131+
}
132+
}
133+
134+
// Increment counter
135+
*counter += 1;
136+
137+
// Re-schedule
138+
let _ = fizzbuzz::spawn_after(*interval);
139+
}
140+
}

0 commit comments

Comments
 (0)