refactor for streamlining
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# Task Checklist
|
||||
# 00 - install rust
|
||||
|
||||
- [ ] Rust toolchain installiert (`rustup`, `cargo`, `rustc`)
|
||||
- [ ] Target `thumbv7m-none-eabi` installiert
|
||||
@@ -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"
|
||||
@@ -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
7
tutorial/01-rust-hello/Cargo.lock
generated
Normal 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"
|
||||
@@ -1,4 +1,4 @@
|
||||
[package]
|
||||
name = "step01_rust_hello_task"
|
||||
name = "rust_hello_task"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
@@ -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/solution.06p5vxa3q8owanxdnt6b423l3.rcgu.o
Normal file
BIN
tutorial/01-rust-hello/solution.06p5vxa3q8owanxdnt6b423l3.rcgu.o
Normal file
Binary file not shown.
Binary file not shown.
BIN
tutorial/01-rust-hello/src/main
Executable file
BIN
tutorial/01-rust-hello/src/main
Executable file
Binary file not shown.
@@ -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.");
|
||||
}
|
||||
BIN
tutorial/01-rust-hello/src/solution
Executable file
BIN
tutorial/01-rust-hello/src/solution
Executable file
Binary file not shown.
7
tutorial/02-rust-types-control/Cargo.lock
generated
Normal file
7
tutorial/02-rust-types-control/Cargo.lock
generated
Normal 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"
|
||||
@@ -1,4 +1,4 @@
|
||||
[package]
|
||||
name = "step01_rust_hello_solution"
|
||||
name = "rust_types_control_task"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
@@ -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.
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
[package]
|
||||
name = "step02_rust_types_control_solution"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
@@ -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} => {}");
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
[package]
|
||||
name = "step02_rust_types_control_task"
|
||||
name = "rust_ownership_borrow_task"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
@@ -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.
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
[package]
|
||||
name = "step03_rust_ownership_borrow_solution"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
@@ -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,
|
||||
@@ -1,4 +1,4 @@
|
||||
[package]
|
||||
name = "step03_rust_ownership_borrow_task"
|
||||
name = "rust_desktop_programm"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
3
tutorial/04-desktop-programm/README.md
Normal file
3
tutorial/04-desktop-programm/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 04 Desktop Programm
|
||||
|
||||
kleines CLI Tool um Fertigkeiten auszuprobieren
|
||||
0
tutorial/04-desktop-programm/src/main.rs
Normal file
0
tutorial/04-desktop-programm/src/main.rs
Normal 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.
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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.
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "step05_led_blink_task"
|
||||
name = "embedded_no_std"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
3
tutorial/05-no-std/README.md
Normal file
3
tutorial/05-no-std/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 05 - Embedded no_std
|
||||
|
||||
Erstes Bare-Metal-Programm mit `#![no_std]`, `#![no_main]` und RTT Logs.
|
||||
@@ -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");
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -1,5 +0,0 @@
|
||||
MEMORY
|
||||
{
|
||||
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
|
||||
RAM : ORIGIN = 0x20000000, LENGTH = 20K
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
[toolchain]
|
||||
channel = "stable"
|
||||
components = ["rustfmt"]
|
||||
targets = ["thumbv7m-none-eabi"]
|
||||
@@ -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"
|
||||
@@ -1,5 +0,0 @@
|
||||
MEMORY
|
||||
{
|
||||
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
|
||||
RAM : ORIGIN = 0x20000000, LENGTH = 20K
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
[toolchain]
|
||||
channel = "stable"
|
||||
components = ["rustfmt"]
|
||||
targets = ["thumbv7m-none-eabi"]
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "step06_button_input_task"
|
||||
name = "led_blink_task"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
3
tutorial/06-led-blink/README.md
Normal file
3
tutorial/06-led-blink/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 06 - LED Blink
|
||||
|
||||
Onboard-LED (PC13, active-low) per Timer toggeln.
|
||||
@@ -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();
|
||||
@@ -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.
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -1,5 +0,0 @@
|
||||
MEMORY
|
||||
{
|
||||
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
|
||||
RAM : ORIGIN = 0x20000000, LENGTH = 20K
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
[toolchain]
|
||||
channel = "stable"
|
||||
components = ["rustfmt"]
|
||||
targets = ["thumbv7m-none-eabi"]
|
||||
@@ -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"
|
||||
@@ -1,5 +0,0 @@
|
||||
MEMORY
|
||||
{
|
||||
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
|
||||
RAM : ORIGIN = 0x20000000, LENGTH = 20K
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
[toolchain]
|
||||
channel = "stable"
|
||||
components = ["rustfmt"]
|
||||
targets = ["thumbv7m-none-eabi"]
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "step05_led_blink_solution"
|
||||
name = "button_input_task"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
3
tutorial/07-button-input/README.md
Normal file
3
tutorial/07-button-input/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 07 - Button Input
|
||||
|
||||
Button an PA0 (Pull-up) lesen und Press/Release als Log ausgeben.
|
||||
@@ -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();
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "step07_analog_readout_task"
|
||||
name = "analog_readout_task"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
3
tutorial/08-analog-readout/README.md
Normal file
3
tutorial/08-analog-readout/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 08 - Analog Readout
|
||||
|
||||
ADC auf PA1 lesen und Werte über RTT streamen.
|
||||
@@ -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();
|
||||
@@ -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.
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -1,5 +0,0 @@
|
||||
MEMORY
|
||||
{
|
||||
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
|
||||
RAM : ORIGIN = 0x20000000, LENGTH = 20K
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
[toolchain]
|
||||
channel = "stable"
|
||||
components = ["rustfmt"]
|
||||
targets = ["thumbv7m-none-eabi"]
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -1,5 +0,0 @@
|
||||
MEMORY
|
||||
{
|
||||
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
|
||||
RAM : ORIGIN = 0x20000000, LENGTH = 20K
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
[toolchain]
|
||||
channel = "stable"
|
||||
components = ["rustfmt"]
|
||||
targets = ["thumbv7m-none-eabi"]
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user