refactor for streamlining

This commit is contained in:
2026-03-11 13:59:56 +01:00
parent a48ba2963d
commit 3112d15eec
91 changed files with 207 additions and 845 deletions

View File

@@ -1,4 +1,4 @@
# Task Checklist
# 00 - install rust
- [ ] Rust toolchain installiert (`rustup`, `cargo`, `rustc`)
- [ ] Target `thumbv7m-none-eabi` installiert

View File

@@ -28,9 +28,14 @@ if ! command -v probe-rs >/dev/null 2>&1; then
cargo install probe-rs-tools
sudo groupadd --system plugdev
sudo usermod -a -G plugdev $USER
probe-rs complete install
else
echo "[setup] probe-rs already installed"
probe-rs --version
fi
probe-rs list
probe-rs info
probe-rs chip list | grep STM32F103C8
echo "[setup] done"

View File

@@ -1,17 +0,0 @@
# 00 - Setup Live (10 min)
## Goal
Jede Station kann Rust-Code bauen und eine Bluepill über ST-Link erkennen.
## Steps
1. install rustup
2. add target
3. add probe-rs
## Done when
1. `rustc`, `cargo`, `probe-rs` verfügbar.
2. `thumbv7m-none-eabi` installiert.
3. `probe-rs list` zeigt die Probe.

7
tutorial/01-rust-hello/Cargo.lock generated Normal file
View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "rust_hello_task"
version = "0.1.0"

View File

@@ -1,4 +1,4 @@
[package]
name = "step01_rust_hello_task"
name = "rust_hello_task"
version = "0.1.0"
edition = "2021"

View File

@@ -1,20 +1,15 @@
# 01 - Rust Hello (5 min)
## Goal
# 01 - Rust Hello
Erstes lauffähiges Rust-Programm, das Daten über `println!` ausgibt.
## Run
- `bash scripts/run-step.sh 01 task`
```bash
cd src/
rustc main.c
./main.c
```
## Tasks
1. Öffne `task/src/main.rs`.
2. Ersetze die TODO-Werte.
3. Starte erneut mit `cargo run`.
## Done when
1. Das Programm kompiliert.
2. Die Ausgabe enthält euren Namen und Workshop-Titel.
```bash
cargo run
```

BIN
tutorial/01-rust-hello/src/main Executable file

Binary file not shown.

View File

@@ -3,7 +3,8 @@ fn main() {
let participant_name = "Your Name";
let workshop_title = "Rust on Embedded @ Didacta";
println!("Hello, {participant_name}!");
println!("Welcome to: {workshop_title}");
// TODO: Insert the strings in the output
println!("Hello, TODO !");
println!("Welcome to: TODO");
println!("Next step: types, control flow, and ownership.");
}

Binary file not shown.

View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "rust_types_control_task"
version = "0.1.0"

View File

@@ -1,4 +1,4 @@
[package]
name = "step01_rust_hello_solution"
name = "rust_types_control_task"
version = "0.1.0"
edition = "2021"

View File

@@ -1,20 +1,3 @@
# 02 - Types and Control Flow (6 min)
## Goal
Mit Typen, `if`, und `match` kleine Entscheidungen ausdrücken.
## Run
- `bash scripts/run-step.sh 02 task`
## Tasks
1. Passe die Schwellwerte in `classify_adc` an.
2. Teste mit mehreren ADC-Werten.
3. Beobachte die Ausgabe von `pressed/released` und `low/medium/high`.
## Done when
1. Das Programm kompiliert.
2. Für unterschiedliche Werte entstehen unterschiedliche Klassifizierungen.

View File

@@ -1,4 +0,0 @@
[package]
name = "step02_rust_types_control_solution"
version = "0.1.0"
edition = "2021"

View File

@@ -16,14 +16,17 @@ fn classify_adc(raw: u16) -> &'static str {
}
fn main() {
// TODO: fill in some values into the arrays
let button_samples = [false, true, true, false];
let adc_samples: [u16; 5] = [120, 900, 1500, 2600, 3900];
for pressed in button_samples {
println!("button: {}", classify_button(pressed));
// call and print the function for the button
println!("button: {}");
}
for raw in adc_samples {
println!("adc raw={raw:4} => {}", classify_adc(raw));
// call and print the function for the button
println!("adc raw={raw:4} => {}");
}
}

View File

@@ -1,4 +1,4 @@
[package]
name = "step02_rust_types_control_task"
name = "rust_ownership_borrow_task"
version = "0.1.0"
edition = "2021"

View File

@@ -1,20 +1,3 @@
# 03 - Ownership and Borrowing (7 min)
## Goal
# 03 - Ownership and Borrowing
Ownership und Borrowing an einem kleinen Robot-State praktisch verstehen.
## Run
- `bash scripts/run-step.sh 03 task`
## Tasks
1. Lies die Funktionen mit `&RobotState` und `&mut RobotState`.
2. Ergänze die TODOs in der Task-Datei.
3. Achte auf Compiler-Fehler, wenn mutable/immutable borrows kollidieren.
## Done when
1. Das Programm kompiliert.
2. LED-State, Button-Count und ADC-Wert werden korrekt aktualisiert.

View File

@@ -1,4 +0,0 @@
[package]
name = "step03_rust_ownership_borrow_solution"
version = "0.1.0"
edition = "2021"

View File

@@ -6,27 +6,31 @@ struct RobotState {
}
fn print_state(state: &RobotState) {
// TODO: print the different elements of RobotState
println!(
"state => led_on={}, button_count={}, last_adc={}",
state.led_on, state.button_count, state.last_adc
"state => led_on={}, button_count={}, last_adc={}",
???
);
}
fn toggle_led(state: &mut RobotState) {
state.led_on = !state.led_on;
// TODO: change the LED state to the inverse of itself
state.led_on = ??
}
fn record_button_press(state: &mut RobotState) {
state.button_count += 1;
// TODO: increase the button counter on press
state.button_count = ??
}
fn update_adc(state: &mut RobotState, raw: u16) {
// TODO: keep this function as the single writer for ADC state.
state.last_adc = raw;
// TODO: update the adc value with the given one
state.last_adc = ??
}
fn main() {
let mut state = RobotState {
// TODO: change the RobotState so we can edit its values
let state = RobotState {
led_on: false,
button_count: 0,
last_adc: 0,

View File

@@ -1,4 +1,4 @@
[package]
name = "step03_rust_ownership_borrow_task"
name = "rust_desktop_programm"
version = "0.1.0"
edition = "2021"

View File

@@ -0,0 +1,3 @@
# 04 Desktop Programm
kleines CLI Tool um Fertigkeiten auszuprobieren

View File

View File

@@ -1,20 +0,0 @@
# 04 - Embedded no_std Hello (8 min)
## Goal
Erstes Bare-Metal-Programm mit `#![no_std]`, `#![no_main]` und RTT Logs.
## Run
- `bash scripts/run-step.sh 04 task`
## Tasks
1. Lies die Top-Level-Attribute in `task/src/main.rs`.
2. Passe die Log-Ausgaben an.
3. Flashe mit `cargo run --release`.
## Done when
1. Firmware läuft auf Bluepill.
2. RTT zeigt zyklisch eine "alive"-Meldung.

View File

@@ -1,22 +0,0 @@
[package]
name = "step04_embedded_no_std_hello_solution"
version = "0.1.0"
edition = "2021"
[dependencies]
cortex-m = "0.7.7"
cortex-m-rt = "0.7.5"
defmt = "0.3.10"
defmt-rtt = "0.4.2"
panic-probe = { version = "0.3.2", features = ["print-defmt"] }
nb = "1.1.0"
[dependencies.stm32f1xx-hal]
version = "0.11.0"
features = ["rt", "stm32f103", "medium"]
[profile.release]
codegen-units = 1
debug = 2
lto = true
opt-level = "z"

View File

@@ -1,22 +0,0 @@
[package]
name = "step04_embedded_no_std_hello_task"
version = "0.1.0"
edition = "2021"
[dependencies]
cortex-m = "0.7.7"
cortex-m-rt = "0.7.5"
defmt = "0.3.10"
defmt-rtt = "0.4.2"
panic-probe = { version = "0.3.2", features = ["print-defmt"] }
nb = "1.1.0"
[dependencies.stm32f1xx-hal]
version = "0.11.0"
features = ["rt", "stm32f103", "medium"]
[profile.release]
codegen-units = 1
debug = 2
lto = true
opt-level = "z"

View File

@@ -1,20 +0,0 @@
# 05 - LED Blink (8 min)
## Goal
Onboard-LED (PC13, active-low) per Timer toggeln.
## Run
- `bash scripts/run-step.sh 05 task`
## Tasks
1. Prüfe in `task/src/main.rs`, welche Pegel "LED an/aus" bedeuten.
2. Passe Blinkfrequenz an.
3. Verifiziere LED und Logs.
## Done when
1. LED blinkt sichtbar.
2. Logs zeigen den Schaltzustand.

View File

@@ -1,5 +1,5 @@
[package]
name = "step05_led_blink_task"
name = "embedded_no_std"
version = "0.1.0"
edition = "2021"

View File

@@ -0,0 +1,3 @@
# 05 - Embedded no_std
Erstes Bare-Metal-Programm mit `#![no_std]`, `#![no_main]` und RTT Logs.

View File

@@ -8,11 +8,9 @@ use {defmt_rtt as _, panic_probe as _};
#[entry]
fn main() -> ! {
// TODO: personalize these log lines.
info!("step04: no_std hello on stm32f103c8");
info!("stm: no_std hello on stm32f103c8");
loop {
// TODO: we want this as a loop
asm::delay(8_000_000);
info!("step04: alive");
}
info!("stm: alive");
}

View File

@@ -8,10 +8,10 @@ use {defmt_rtt as _, panic_probe as _};
#[entry]
fn main() -> ! {
info!("step04: boot ok");
info!("boot ok");
loop {
asm::delay(8_000_000);
info!("step04: alive");
info!("alive");
}
}

View File

@@ -1,20 +0,0 @@
# 06 - Button Input (6 min)
## Goal
Button an PA0 (Pull-up) lesen und Press/Release als Log ausgeben.
## Run
- `bash scripts/run-step.sh 06 task`
## Tasks
1. Verdrahtung prüfen: PA0 -> Button -> GND.
2. Starte `task` und beobachte Logs.
3. Passe Polling-Intervall an.
## Done when
1. Pressed/Released wird korrekt erkannt.
2. Keine Flut von Wiederhol-Logs bei gehaltenem Taster.

View File

@@ -1,12 +0,0 @@
[target.thumbv7m-none-eabi]
runner = "probe-rs run --chip STM32F103C8"
rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
]
[build]
target = "thumbv7m-none-eabi"
[env]
DEFMT_LOG = "info"

View File

@@ -1,22 +0,0 @@
[package]
name = "step06_button_input_solution"
version = "0.1.0"
edition = "2021"
[dependencies]
cortex-m = "0.7.7"
cortex-m-rt = "0.7.5"
defmt = "0.3.10"
defmt-rtt = "0.4.2"
panic-probe = { version = "0.3.2", features = ["print-defmt"] }
nb = "1.1.0"
[dependencies.stm32f1xx-hal]
version = "0.11.0"
features = ["rt", "stm32f103", "medium"]
[profile.release]
codegen-units = 1
debug = 2
lto = true
opt-level = "z"

View File

@@ -1,5 +0,0 @@
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
RAM : ORIGIN = 0x20000000, LENGTH = 20K
}

View File

@@ -1,4 +0,0 @@
[toolchain]
channel = "stable"
components = ["rustfmt"]
targets = ["thumbv7m-none-eabi"]

View File

@@ -1,12 +0,0 @@
[target.thumbv7m-none-eabi]
runner = "probe-rs run --chip STM32F103C8"
rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
]
[build]
target = "thumbv7m-none-eabi"
[env]
DEFMT_LOG = "info"

View File

@@ -1,5 +0,0 @@
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
RAM : ORIGIN = 0x20000000, LENGTH = 20K
}

View File

@@ -1,4 +0,0 @@
[toolchain]
channel = "stable"
components = ["rustfmt"]
targets = ["thumbv7m-none-eabi"]

View File

@@ -1,5 +1,5 @@
[package]
name = "step06_button_input_task"
name = "led_blink_task"
version = "0.1.0"
edition = "2021"

View File

@@ -0,0 +1,3 @@
# 06 - LED Blink
Onboard-LED (PC13, active-low) per Timer toggeln.

View File

@@ -16,7 +16,7 @@ fn main() -> ! {
let mut gpioc = dp.GPIOC.split(&mut rcc);
// Bluepill onboard LED on PC13 is active-low.
let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
// TODO: create LED Pin Input
let mut timer = Timer::syst(cp.SYST, &rcc.clocks).counter_hz();
timer.start(2.Hz()).unwrap();

View File

@@ -1,20 +0,0 @@
# 07 - Analog Readout (6 min)
## Goal
ADC auf PA1 lesen und Werte über RTT streamen.
## Run
- `bash scripts/run-step.sh 07 task`
## Tasks
1. Verdrahtung prüfen: Analogsignal an PA1.
2. Werte ausgeben und in drei Bereiche klassifizieren.
3. Potentiometer/Sensor bewegen und Änderung beobachten.
## Done when
1. Rohwert ändert sich mit Eingangsspannung.
2. Klassifizierung (`low/medium/high`) reagiert sinnvoll.

View File

@@ -1,12 +0,0 @@
[target.thumbv7m-none-eabi]
runner = "probe-rs run --chip STM32F103C8"
rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
]
[build]
target = "thumbv7m-none-eabi"
[env]
DEFMT_LOG = "info"

View File

@@ -1,22 +0,0 @@
[package]
name = "step07_analog_readout_solution"
version = "0.1.0"
edition = "2021"
[dependencies]
cortex-m = "0.7.7"
cortex-m-rt = "0.7.5"
defmt = "0.3.10"
defmt-rtt = "0.4.2"
panic-probe = { version = "0.3.2", features = ["print-defmt"] }
nb = "1.1.0"
[dependencies.stm32f1xx-hal]
version = "0.11.0"
features = ["rt", "stm32f103", "medium"]
[profile.release]
codegen-units = 1
debug = 2
lto = true
opt-level = "z"

View File

@@ -1,5 +0,0 @@
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
RAM : ORIGIN = 0x20000000, LENGTH = 20K
}

View File

@@ -1,4 +0,0 @@
[toolchain]
channel = "stable"
components = ["rustfmt"]
targets = ["thumbv7m-none-eabi"]

View File

@@ -1,12 +0,0 @@
[target.thumbv7m-none-eabi]
runner = "probe-rs run --chip STM32F103C8"
rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
]
[build]
target = "thumbv7m-none-eabi"
[env]
DEFMT_LOG = "info"

View File

@@ -1,5 +0,0 @@
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
RAM : ORIGIN = 0x20000000, LENGTH = 20K
}

View File

@@ -1,4 +0,0 @@
[toolchain]
channel = "stable"
components = ["rustfmt"]
targets = ["thumbv7m-none-eabi"]

View File

@@ -1,5 +1,5 @@
[package]
name = "step05_led_blink_solution"
name = "button_input_task"
version = "0.1.0"
edition = "2021"

View File

@@ -0,0 +1,3 @@
# 07 - Button Input
Button an PA0 (Pull-up) lesen und Press/Release als Log ausgeben.

View File

@@ -15,8 +15,7 @@ fn main() -> ! {
let mut rcc = dp.RCC.constrain();
let mut gpioa = dp.GPIOA.split(&mut rcc);
// Button wiring: PA0 -> button -> GND
let button = gpioa.pa0.into_pull_up_input(&mut gpioa.crl);
// TODO: Button wiring: PA0 -> button -> GND
let mut timer = Timer::syst(cp.SYST, &rcc.clocks).counter_hz();
timer.start(40.Hz()).unwrap();
@@ -24,15 +23,9 @@ fn main() -> ! {
let mut last_pressed = false;
loop {
let pressed = button.is_low();
if pressed != last_pressed {
if pressed {
info!("button: pressed");
} else {
info!("button: released");
}
last_pressed = pressed;
}
// TODO: get the current button status
// TODO: print a message when the button is pressed and released
// Poll at 25ms to avoid too much log spam.
block!(timer.wait()).unwrap();

View File

@@ -1,5 +1,5 @@
[package]
name = "step07_analog_readout_task"
name = "analog_readout_task"
version = "0.1.0"
edition = "2021"

View File

@@ -0,0 +1,3 @@
# 08 - Analog Readout
ADC auf PA1 lesen und Werte über RTT streamen.

View File

@@ -24,8 +24,7 @@ fn main() -> ! {
let mut rcc = dp.RCC.constrain();
let mut gpioa = dp.GPIOA.split(&mut rcc);
let mut adc = Adc::new(dp.ADC1, &mut rcc);
let mut analog_pin = gpioa.pa1.into_analog(&mut gpioa.crl);
// TODO: set up ADC and ADC Pin and read
let mut timer = Timer::syst(cp.SYST, &rcc.clocks).counter_hz();
timer.start(10.Hz()).unwrap();

View File

@@ -1,22 +0,0 @@
# 08 - Final Combined (4 min)
## Goal
Blink + Button + ADC in einem Programm kombinieren.
## Behavior
1. ADC steuert Blink-Intervall.
2. Button toggelt Betriebsmodus:
- `Mode::Blinking`
- `Mode::ForcedOff`
## Run
- `bash scripts/run-step.sh 08 task`
## Done when
1. LED-Verhalten ändert sich per Button.
2. ADC beeinflusst Blinkgeschwindigkeit im Blink-Modus.
3. Logs zeigen Mode, ADC und Delay.

View File

@@ -1,12 +0,0 @@
[target.thumbv7m-none-eabi]
runner = "probe-rs run --chip STM32F103C8"
rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
]
[build]
target = "thumbv7m-none-eabi"
[env]
DEFMT_LOG = "info"

View File

@@ -1,22 +0,0 @@
[package]
name = "step08_final_combined_solution"
version = "0.1.0"
edition = "2021"
[dependencies]
cortex-m = "0.7.7"
cortex-m-rt = "0.7.5"
defmt = "0.3.10"
defmt-rtt = "0.4.2"
panic-probe = { version = "0.3.2", features = ["print-defmt"] }
nb = "1.1.0"
[dependencies.stm32f1xx-hal]
version = "0.11.0"
features = ["rt", "stm32f103", "medium"]
[profile.release]
codegen-units = 1
debug = 2
lto = true
opt-level = "z"

View File

@@ -1,5 +0,0 @@
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
RAM : ORIGIN = 0x20000000, LENGTH = 20K
}

View File

@@ -1,4 +0,0 @@
[toolchain]
channel = "stable"
components = ["rustfmt"]
targets = ["thumbv7m-none-eabi"]

View File

@@ -1,83 +0,0 @@
#![no_std]
#![no_main]
use cortex_m_rt::entry;
use defmt::info;
use nb::block;
use stm32f1xx_hal::{adc::Adc, pac, prelude::*, timer::Timer};
use {defmt_rtt as _, panic_probe as _};
#[derive(Clone, Copy, PartialEq, Eq)]
enum Mode {
Blinking,
ForcedOff,
}
fn interval_from_adc(raw: u16) -> u32 {
100 + (u32::from(raw) * 800 / 4095)
}
#[entry]
fn main() -> ! {
let cp = cortex_m::Peripherals::take().unwrap();
let dp = pac::Peripherals::take().unwrap();
let mut rcc = dp.RCC.constrain();
let mut gpioa = dp.GPIOA.split(&mut rcc);
let mut gpioc = dp.GPIOC.split(&mut rcc);
let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
let button = gpioa.pa0.into_pull_up_input(&mut gpioa.crl);
let mut adc = Adc::new(dp.ADC1, &mut rcc);
let mut analog_pin = gpioa.pa1.into_analog(&mut gpioa.crl);
let mut tick = Timer::syst(cp.SYST, &rcc.clocks).counter_hz();
tick.start(100.Hz()).unwrap();
let mut mode = Mode::Blinking;
let mut last_pressed = false;
let mut led_on = false;
let mut elapsed_ms: u32 = 0;
loop {
let pressed = button.is_low();
if pressed && !last_pressed {
mode = if mode == Mode::Blinking {
info!("mode -> ForcedOff");
Mode::ForcedOff
} else {
info!("mode -> Blinking");
Mode::Blinking
};
}
last_pressed = pressed;
let raw: u16 = adc.read(&mut analog_pin).unwrap();
let interval_ms = interval_from_adc(raw);
match mode {
Mode::Blinking => {
elapsed_ms += 10;
if elapsed_ms >= interval_ms {
elapsed_ms = 0;
led_on = !led_on;
if led_on {
led.set_low();
} else {
led.set_high();
}
info!("mode=Blinking adc={} interval_ms={} led_on={}", raw, interval_ms, led_on);
}
}
Mode::ForcedOff => {
led_on = false;
led.set_high();
elapsed_ms = 0;
info!("mode=ForcedOff adc={} interval_ms={}", raw, interval_ms);
}
}
block!(tick.wait()).unwrap();
}
}

View File

@@ -1,12 +0,0 @@
[target.thumbv7m-none-eabi]
runner = "probe-rs run --chip STM32F103C8"
rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
]
[build]
target = "thumbv7m-none-eabi"
[env]
DEFMT_LOG = "info"

View File

@@ -1,22 +0,0 @@
[package]
name = "step08_final_combined_task"
version = "0.1.0"
edition = "2021"
[dependencies]
cortex-m = "0.7.7"
cortex-m-rt = "0.7.5"
defmt = "0.3.10"
defmt-rtt = "0.4.2"
panic-probe = { version = "0.3.2", features = ["print-defmt"] }
nb = "1.1.0"
[dependencies.stm32f1xx-hal]
version = "0.11.0"
features = ["rt", "stm32f103", "medium"]
[profile.release]
codegen-units = 1
debug = 2
lto = true
opt-level = "z"

View File

@@ -1,5 +0,0 @@
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
RAM : ORIGIN = 0x20000000, LENGTH = 20K
}

View File

@@ -1,4 +0,0 @@
[toolchain]
channel = "stable"
components = ["rustfmt"]
targets = ["thumbv7m-none-eabi"]

View File

@@ -1,85 +0,0 @@
#![no_std]
#![no_main]
use cortex_m_rt::entry;
use defmt::info;
use nb::block;
use stm32f1xx_hal::{adc::Adc, pac, prelude::*, timer::Timer};
use {defmt_rtt as _, panic_probe as _};
#[derive(Clone, Copy, PartialEq, Eq)]
enum Mode {
Blinking,
ForcedOff,
}
fn interval_from_adc(raw: u16) -> u32 {
// Map 0..4095 -> 100..900 ms
100 + (u32::from(raw) * 800 / 4095)
}
#[entry]
fn main() -> ! {
let cp = cortex_m::Peripherals::take().unwrap();
let dp = pac::Peripherals::take().unwrap();
let mut rcc = dp.RCC.constrain();
let mut gpioa = dp.GPIOA.split(&mut rcc);
let mut gpioc = dp.GPIOC.split(&mut rcc);
let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
let button = gpioa.pa0.into_pull_up_input(&mut gpioa.crl);
let mut adc = Adc::new(dp.ADC1, &mut rcc);
let mut analog_pin = gpioa.pa1.into_analog(&mut gpioa.crl);
// Fast base tick: all app timing derives from this.
let mut tick = Timer::syst(cp.SYST, &rcc.clocks).counter_hz();
tick.start(100.Hz()).unwrap(); // 10 ms
let mut mode = Mode::Blinking;
let mut last_pressed = false;
let mut led_on = false;
let mut elapsed_ms: u32 = 0;
loop {
let pressed = button.is_low();
if pressed && !last_pressed {
mode = if mode == Mode::Blinking {
info!("mode -> ForcedOff");
Mode::ForcedOff
} else {
info!("mode -> Blinking");
Mode::Blinking
};
}
last_pressed = pressed;
let raw: u16 = adc.read(&mut analog_pin).unwrap();
let interval_ms = interval_from_adc(raw);
match mode {
Mode::Blinking => {
elapsed_ms += 10;
if elapsed_ms >= interval_ms {
elapsed_ms = 0;
led_on = !led_on;
if led_on {
led.set_low(); // active-low
} else {
led.set_high();
}
info!("mode=Blinking adc={} interval_ms={} led_on={}", raw, interval_ms, led_on);
}
}
Mode::ForcedOff => {
led_on = false;
led.set_high();
elapsed_ms = 0;
info!("mode=ForcedOff adc={} interval_ms={}", raw, interval_ms);
}
}
block!(tick.wait()).unwrap();
}
}