Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cargo/config → .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[target.thumbv7m-none-eabi]
runner = 'arm-none-eabi-gdb'
runner = 'stm32cubeprogrammer'


rustflags = [
Expand Down
84 changes: 84 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: CI

on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]

env:
CARGO_TERM_COLOR: always

jobs:
check:
name: Check
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- stable
- beta
features:
- stm32l100
- stm32l100,rt
- stm32l151
- stm32l151,rt
- stm32l152
- stm32l152,rt
- stm32l162
- stm32l162,rt
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
targets: thumbv7m-none-eabi
- name: Check
run: cargo check --features=${{ matrix.features }}

build:
name: Build
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- stable
- beta
features:
- stm32l100,rt
- stm32l151,rt
- stm32l152,rt
- stm32l162,rt
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
targets: thumbv7m-none-eabi
- name: Build
run: cargo build --features=${{ matrix.features }}
- name: Build examples
run: cargo build --features=${{ matrix.features }} --examples

clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
targets: thumbv7m-none-eabi
components: clippy
- name: Clippy
run: cargo clippy --features=stm32l151,rt -- -D warnings

fmt:
name: Rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: Format check
run: cargo fmt --all -- --check
22 changes: 20 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
# Rust build artifacts
/target/
**/*.orig
**/*.rs.bk
Cargo.lock
**/*.rs.bk
**/*.orig

# IDE and editor files
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store

# Debug files
*.elf
*.bin
*.hex
*.map

# GDB history
.gdb_history
41 changes: 18 additions & 23 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,38 +21,33 @@ repository = "https://github.com/stm32-rs/stm32l1xx-hal"
version = "0.1.0"

[dependencies]
cortex-m = "0.5.8"
nb = "0.1.1"
stm32l1 = "0.5.0"

[dependencies.bare-metal]
features = ["const-fn"]
version = "0.2.4"

[dependencies.cast]
default-features = false
version = "0.2.2"

[dependencies.embedded-hal]
features = ["unproven"]
version = "0.2.3"

[dependencies.void]
default-features = false
version = "1.0.2"
cortex-m = "0.7.6"
cortex-m-rt = "0.7.1"
nb = "1"
stm32l1 = "0.15.1"
bare-metal = { version = "1" }
embedded-hal = { features = ["unproven"], version = "0.2.7" }
void = { default-features = false, version = "1.0.2" }
cast = { default-features = false, version = "0.3.0" }
fugit = "0.3.6"
fugit-timer = "0.1.3"
time = { version = "0.3.14", default-features = false }
defmt = { version = "0.3", optional = true }

[dev-dependencies]
cortex-m-rt = "0.6.7"
cortex-m-semihosting = "0.3.2"
panic-semihosting = "0.5.1"
cortex-m-rtic = "0.5.5"
cortex-m-rt = "0.7.1"
cortex-m-semihosting = "0.5.0"
panic-semihosting = "0.6.0"
cortex-m-rtic = "1.1.3"

[features]
default = []
rt = ["stm32l1/rt"]
stm32l100 = ["stm32l1/stm32l100"]
stm32l151 = ["stm32l1/stm32l151"]
stm32l152 = ["stm32l1/stm32l151"]
stm32l162 = ["stm32l1/stm32l162"]
defmt = ["dep:defmt"]

[profile.dev]
codegen-units = 1
Expand Down
112 changes: 112 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Examples

This directory contains example applications demonstrating the features of the `stm32l1xx-hal` crate.

## Building Examples

To build an example:

```bash
cargo build --example <example_name> --features stm32l152 --target thumbv7m-none-eabi
```

Replace `stm32l152` with your target MCU feature (`stm32l100`, `stm32l151`, `stm32l152`, or `stm32l162`).

## Available Examples

### GPIO Examples
- **`blinky.rs`** - Simple LED blinking using busy-wait loops
- **`blinky_delay.rs`** - LED blinking using delay abstraction
- **`blinky_timer.rs`** - LED blinking using hardware timer
- **`button.rs`** - Reading button input
- **`button_irq.rs`** - Button input with interrupt handling
- **`gpio_interrupt.rs`** - GPIO interrupt configuration and handling

### Peripheral Examples
- **`adc.rs`** - Analog to Digital Converter (ADC) reading
- **`adc_pwm.rs`** - ADC combined with PWM output
- **`dac.rs`** - Digital to Analog Converter (DAC) output
- **`dma.rs`** - Direct Memory Access (DMA) usage
- **`i2c.rs`** - I2C communication
- **`pwm.rs`** - Pulse Width Modulation (PWM) output
- **`qei.rs`** - Quadrature Encoder Interface
- **`serial.rs`** - UART/Serial communication
- **`spi.rs`** - SPI communication
- **`timer.rs`** - Hardware timer with interrupts
- **`watchdog.rs`** - Watchdog timer configuration

### RTC Examples
- **`rtc_backup_simple.rs`** - RTC backup register usage and power-loss detection
- Demonstrates backup register read/write
- Shows how to detect VBAT power loss
- Implements boot counter that persists across resets

- **`rtc_backup.rs`** - Complete RTC example with time keeping
- RTC initialization with magic number check
- Setting and reading date/time
- Backup register for boot counting
- RTC wakeup timer usage

### Debug Examples
- **`hello.rs`** - Simple "Hello World" via semihosting
- **`itm.rs`** - ITM (Instrumentation Trace Macrocell) output
- **`rtic.rs`** - Real-Time Interrupt-driven Concurrency (RTIC) framework example

## RTC Backup Register Features

The RTC examples demonstrate new functionality added to the HAL:

### Power-Loss Detection
```rust
const MAGIC_NUMBER: u32 = 0x32F2;

if !rtc.is_initialized(0, MAGIC_NUMBER) {
// First boot or VBAT was lost - initialize RTC
rtc.set_datetime(&datetime)?;
rtc.mark_initialized(0, MAGIC_NUMBER);
}
```

### Persistent Storage
RTC backup registers (0-31) retain data as long as VBAT is supplied:

```rust
// Read boot counter
let count = rtc.read_backup_register(1);

// Increment and save
rtc.write_backup_register(1, count + 1);
```

### Use Cases
- Boot counter
- Configuration flags that persist across resets
- Timestamps for power-loss events
- System state recovery after unexpected resets
- Calibration data that shouldn't be lost

## Hardware Requirements

Most examples require:
- STM32L1xx development board (e.g., STM32L152 Discovery)
- Debug probe (ST-Link V2 or compatible)
- For RTC examples: 32.768 kHz crystal (LSE) or coin cell battery on VBAT

## Running Examples

1. Connect your debug probe to the target board
2. Build the example
3. Flash using your preferred tool:
```bash
# Using cargo-embed
cargo embed --example rtc_backup_simple --features stm32l152

# Using probe-run
cargo run --example rtc_backup_simple --features stm32l152
```

## Troubleshooting

- If RTC examples don't work, ensure the LSE crystal is properly connected
- For backup register persistence, VBAT must be connected to a battery or VDD
- Some examples require semihosting support in your debug environment
10 changes: 4 additions & 6 deletions examples/button_irq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ use core::cell::RefCell;
use core::ops::DerefMut;

use cortex_m::interrupt::Mutex;
use hal::exti::TriggerEdge;
use hal::prelude::*;
use hal::exti::{ExtiTrait, TriggerEdge};
use hal::stm32::{self, interrupt, Interrupt, EXTI};
use rt::entry;
use sh::hprintln;
Expand All @@ -23,9 +22,8 @@ static INT: Mutex<RefCell<Option<EXTI>>> = Mutex::new(RefCell::new(None));
#[entry]
fn main() -> ! {
let dp = stm32::Peripherals::take().unwrap();
let mut cp = cortex_m::Peripherals::take().unwrap();

cp.NVIC.enable(Interrupt::EXTI0);
unsafe { cortex_m::peripheral::NVIC::unmask(Interrupt::EXTI0) };
dp.EXTI.listen(0, TriggerEdge::Falling);

cortex_m::interrupt::free(move |cs| {
Expand All @@ -40,11 +38,11 @@ fn EXTI0() {
static mut COUNT: i32 = 0;

*COUNT += 1;
hprintln!("CLICK # {}", COUNT).unwrap();
hprintln!("CLICK # {}", COUNT);

cortex_m::interrupt::free(|cs| {
if let &mut Some(ref mut exti) = INT.borrow(cs).borrow_mut().deref_mut() {
exti.clear_irq(0);
exti.clear_interrupt_pending_bit(0);
}
});
}
2 changes: 1 addition & 1 deletion examples/dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ fn main() -> ! {
let dma1 = dp.DMA1.dma(&mut rcc);
let dma2 = dp.DMA2.dma(&mut rcc);

hprintln!("DMA1: {:?}, DMA2: {:?}", dma1, dma2).unwrap();
hprintln!("DMA1: {:?}, DMA2: {:?}", dma1, dma2);
loop {}
}
Loading