# Rust on Embedded

### Didacta Workshop

STM32F103C8 Bluepill + ST-Link + Rust

## Workshop Goal

- Understand core Rust basics
- Build and flash no_std firmware
- Blink LED, read button, read analog input
- See output with probe-rs RTT logs

## Flow (60 min)

- 00 setup, 01-03 Rust basics
- 04 first embedded app
- 05 LED blink
- 06 button input
- 07 analog readout
- 08 final combined app

## How We Work

- Edit only `task/` folders
- Use `solution/` only when stuck
- One step at a time, linear slides

## Step 00 Task: Setup Live

Next task: Prepare host + probe tools.

Learn: Embedded Rust toolchain basics.

    bash scripts/setup-live.sh
    bash scripts/verify-host.sh
    bash scripts/verify-probe.sh

## Step 00 Solution

- `rustup`, `cargo`, `probe-rs` available
- Target `thumbv7m-none-eabi` installed
- `probe-rs list` sees ST-Link
- `probe-rs chip list` contains `STM32F103C8`

## Step 01 Task: Rust Hello

Next task: Edit the TODO values and run.

Learn: `fn main`, variables, `println!`.

    bash scripts/run-step.sh 01 task

## Step 01 Solution

- Program compiles and runs with `cargo run`
- Console output shows your name and workshop title
- You can navigate the task/solution structure

## Step 02 Task: Types + Control Flow

Next task: Tune threshold logic in `classify_adc`.

Learn: explicit types, `if`, `match`.

    bash scripts/run-step.sh 02 task

## Step 02 Solution

- ADC values map to low/medium/high
- Button states map to pressed/released
- Program output changes correctly with input values

## Step 03 Task: Ownership + Borrowing

Next task: Complete/update state mutation functions.

Learn: `&T` vs `&mut T`, safe mutation design.

    bash scripts/run-step.sh 03 task

## Step 03 Solution

- State is read via immutable reference
- State changes happen through mutable references
- Compiler enforces safe access patterns

## Step 04 Task: Embedded no_std Hello

Next task: Flash first no_std firmware and watch RTT logs.

Learn: `#![no_std]`, `#![no_main]`, `#[entry]`.

    bash scripts/run-step.sh 04 task

## Step 04 Solution

- Firmware flashes to Bluepill
- RTT shows boot + alive messages
- You now have a working embedded Rust baseline

## Step 05 Task: LED Blink

Next task: Toggle PC13 in a timed loop.

Learn: HAL GPIO output + active-low LED behavior.

    bash scripts/run-step.sh 05 task

## Step 05 Solution

- PC13 low = LED on, PC13 high = LED off
- Timer loop controls blink frequency
- RTT logs match LED state changes

## Step 06 Task: Button Input

Next task: Read PA0 with pull-up and detect transitions.

Learn: digital input polling + simple edge detection.

    bash scripts/run-step.sh 06 task

## Step 06 Solution

- Pressed/released events are logged correctly
- No repeated spam while button is held
- Wiring pattern: PA0 -> button -> GND

## Step 07 Task: Analog Readout

Next task: Read ADC on PA1 and print values.

Learn: one-shot ADC + value classification.

    bash scripts/run-step.sh 07 task

## Step 07 Solution

- ADC raw value changes with analog input
- Classification low/medium/high works
- Periodic readout appears in RTT console

## Step 08 Task: Final Combined

Next task: Integrate LED + button + ADC behavior.

Learn: small embedded state machine.

    bash scripts/run-step.sh 08 task

## Step 08 Solution

- Button toggles mode: Blinking / ForcedOff
- ADC value controls blink interval in Blinking mode
- Integrated firmware runs stable with logs

## Workshop Wrap-up

- You moved from Rust basics to real MCU firmware
- You used no_std, HAL GPIO, button input, and ADC
- Next: extend with UART, interrupts, or Embassy async