Skip to content

Commit 2b33693

Browse files
bors[bot]barafaelAfoHT
authored
Merge #35
35: Add v1.0 L4 heartbeat example r=AfoHT a=barafael Confirmed working on a shady STM32L476RET6 board :) Co-authored-by: Rafael Bachmann <rafael.bachmann.93@gmail.com> Co-authored-by: Henrik Tjäder <henrik@tjaders.com>
2 parents da09fc1 + a52f011 commit 2b33693

File tree

7 files changed

+189
-0
lines changed

7 files changed

+189
-0
lines changed

.github/dependabot.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,7 @@ updates:
6161
directory: "/rtic_v1/stm32f4_pwm_monitor"
6262
schedule:
6363
interval: "weekly"
64+
- package-ecosystem: "cargo"
65+
directory: "/rtic_v1/stm32l4_heartbeat"
66+
schedule:
67+
interval: "weekly"
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2+
# uncomment ONE of these three option to make `cargo run` start a GDB session
3+
# which option to pick depends on your system
4+
# runner = "arm-none-eabi-gdb -q -x jlink.gdb"
5+
# runner = "arm-none-eabi-gdb -q -x openocd.gdb"
6+
runner = "gdb-multiarch -q -x openocd.gdb"
7+
# runner = "gdb -q -x openocd.gdb"
8+
9+
rustflags = [
10+
# LLD (shipped with the Rust toolchain) is used as the default linker
11+
"-C", "link-arg=-Tlink.x",
12+
13+
# if you run into problems with LLD switch to the GNU linker by commenting out
14+
# this line
15+
# "-C", "linker=arm-none-eabi-ld",
16+
17+
# if you need to link to pre-compiled C libraries provided by a C toolchain
18+
# use GCC as the linker by commenting out both lines above and then
19+
# uncommenting the three lines below
20+
# "-C", "linker=arm-none-eabi-gcc",
21+
# "-C", "link-arg=-Wl,-Tlink.x",
22+
# "-C", "link-arg=-nostartfiles",
23+
24+
# uncomment for unchecked wrapping arithmetics also in dev mode
25+
# "-Z", "force-overflow-checks=off",
26+
]
27+
28+
[build]
29+
# Pick ONE of these compilation targets
30+
# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
31+
# target = "thumbv7m-none-eabi" # Cortex-M3
32+
# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU)
33+
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 = "STM32L412"
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: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
[package]
2+
name = "stm32l4_heartbeat"
3+
categories = ["embedded", "no-std"]
4+
authors = [
5+
"arrowcircle",
6+
"Emil Fresk <emil.fresk@gmail.com>",
7+
"Domenico Andreoli <domenico.andreoli@linux.com>",
8+
]
9+
description = "Heartbeat for stm32l4xx"
10+
keywords = ["arm", "cortex-m"]
11+
license = "MIT OR Apache-2.0"
12+
version = "0.1.0"
13+
edition = "2021"
14+
15+
[dependencies]
16+
embedded-hal = "0.2.6"
17+
cortex-m-rtic = "1.0.0"
18+
stm32l4xx-hal = { version = "0.7.1", features = ["rt", "stm32l412"] }
19+
heapless = "0.7.10"
20+
systick-monotonic = "1.0.0"
21+
panic-rtt-target = { version = "0.1.2", features = ["cortex-m"] }
22+
rtt-target = { version = "0.3.1", features = ["cortex-m"] }
23+
24+
# this lets you use `cargo fix`!
25+
[[bin]]
26+
name = "stm32l4_heartbeat"
27+
test = false
28+
bench = false
29+
30+
[profile.dev]
31+
opt-level = 1
32+
codegen-units = 16
33+
debug = true
34+
lto = false
35+
36+
[profile.release]
37+
opt-level = "s" # optimize for size
38+
codegen-units = 1 # better optimizations
39+
debug = true # symbols are nice and they don't increase the size on Flash
40+
lto = true # better optimizations

rtic_v1/stm32l4_heartbeat/memory.x

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
MEMORY
2+
{
3+
/* NOTE 1 K = 1 KiBi = 1024 bytes */
4+
/* TODO Adjust these memory regions to match your device memory layout */
5+
/* These values correspond to the LM3S6965, one of the few devices QEMU can emulate */
6+
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
7+
RAM : ORIGIN = 0x20000000, LENGTH = 20K
8+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#![deny(unsafe_code)]
2+
#![deny(warnings)]
3+
#![no_main]
4+
#![no_std]
5+
6+
use panic_rtt_target as _;
7+
use rtic::app;
8+
use rtt_target::{rprintln, rtt_init_print};
9+
use stm32l4xx_hal::gpio::{gpiob::PB3, Output, PushPull};
10+
use stm32l4xx_hal::prelude::*;
11+
use systick_monotonic::{fugit::Duration, Systick};
12+
13+
#[app(device = stm32l4xx_hal::pac, dispatchers = [SPI3])]
14+
mod app {
15+
use super::*;
16+
17+
#[shared]
18+
struct Shared {}
19+
20+
#[local]
21+
struct Local {
22+
led: PB3<Output<PushPull>>,
23+
intervals: [u32; 6],
24+
}
25+
26+
#[monotonic(binds = SysTick, default = true)]
27+
type MonoTimer = Systick<1000>;
28+
29+
#[init]
30+
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
31+
// Setup clocks
32+
let mut flash = cx.device.FLASH.constrain();
33+
let mut rcc = cx.device.RCC.constrain();
34+
let mut pwr = cx.device.PWR.constrain(&mut rcc.apb1r1);
35+
let mono = Systick::new(cx.core.SYST, 72_000_000);
36+
37+
rtt_init_print!();
38+
rprintln!("init");
39+
40+
let _clocks = rcc.cfgr.sysclk(72.MHz()).freeze(&mut flash.acr, &mut pwr);
41+
42+
// Setup LED
43+
let mut gpiob = cx.device.GPIOB.split(&mut rcc.ahb2);
44+
let mut led = gpiob
45+
.pb3
46+
.into_push_pull_output(&mut gpiob.moder, &mut gpiob.otyper);
47+
led.set_low();
48+
49+
// Simple heart beat LED on/off sequence
50+
let intervals: [u32; 6] = [
51+
30, // P Wave
52+
40, // PR Segment
53+
120, // QRS Complex
54+
30, // ST Segment
55+
60, // T Wave
56+
720, // Rest
57+
];
58+
59+
// Schedule the blinking task
60+
blink::spawn(0).unwrap();
61+
62+
(Shared {}, Local { led, intervals }, init::Monotonics(mono))
63+
}
64+
65+
#[idle]
66+
fn idle(_: idle::Context) -> ! {
67+
loop {
68+
core::hint::spin_loop();
69+
}
70+
}
71+
72+
#[task(local = [led, intervals])]
73+
fn blink(cx: blink::Context, state: usize) {
74+
rprintln!("blink");
75+
let duration = cx.local.intervals[state];
76+
let next_state = (state + 1) % cx.local.intervals.len();
77+
78+
cx.local.led.toggle();
79+
80+
let _ = blink::spawn_after(
81+
Duration::<u64, 1, 1000>::from_ticks(duration as u64),
82+
next_state,
83+
);
84+
}
85+
}

0 commit comments

Comments
 (0)