- Rust 89.4%
- Shell 9.8%
- GDB 0.5%
- RPC 0.3%
|
|
||
|---|---|---|
| .cargo | ||
| .claude | ||
| .forgejo/workflows | ||
| .vscode | ||
| scripts | ||
| src | ||
| tests | ||
| .DS_Store | ||
| .gitignore | ||
| build.rs | ||
| Cargo.toml | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| coverage.sh | ||
| deploy.sh | ||
| deploy_direct.sh | ||
| deploy_main_tmp.sh | ||
| deploy_main_tmp_direct.sh | ||
| deploy_tmp.sh | ||
| deploy_tmp_direct.sh | ||
| firmware_deep_sleep.bin | ||
| LICENSE | ||
| memory_bootloader.x | ||
| memory_direct.x | ||
| openocd.cfg | ||
| openocd.gdb | ||
| README.md | ||
| samd21.cfg | ||
| test.sh | ||
SAMD21 RTIC Security Sensor
Embedded security sensor firmware for SAMD21 microcontroller using RTIC framework.
Overview
This firmware implements a security sensor system that monitors door state and vibration, communicates via LoRa (SX1278) with encrypted messages, and includes watchdog protection and key management.
Features
- ✅ Door sensor monitoring: Real-time door state detection via GPIO interrupt
- ✅ Vibration detection: Tamper detection using SW420 vibration sensor
- ✅ LoRa communication: Long-range wireless communication via SX1278
- ✅ Encrypted communication: ChaCha20Poly1305 encryption using Sigil protocol
- ✅ Hardware RNG: ATECC608x for Sigil handshake and encrypted event nonces
- ✅ Watchdog protection: 16-second watchdog timer with automatic reset detection
- ✅ Retry logic: Automatic retry for LoRa operations with 500ms delay
- ✅ Error handling: Comprehensive error handling with LED signaling
Hardware Requirements
- MCU: SAMD21G18A
- LoRa Module: SX1278
- Sensors:
- Door sensor (magnetic switch) on PA06
- Vibration sensor (SW420) on PA09
- Indicators:
- Status LED on PA21
- Buzzer on PA19 (GPIO, active buzzer)
- Error LED on PA14
- Init LED on PA18
Pin Configuration
| Function | Pin | Description |
|---|---|---|
| LoRa SPI SCK | PB11 | SPI clock |
| LoRa SPI MOSI | PB10 | SPI data out |
| LoRa SPI MISO | PA12 | SPI data in |
| LoRa NSS | PA15 | SPI chip select |
| LoRa RST | PA20 | Reset pin |
| LoRa DIO0 | PA07 | Interrupt pin (EIC Ch7) |
| Door Sensor | PA06 | Door state (EIC Ch6) |
| Vibration | PA09 | Vibration detection (EIC Ch9) |
| Entropy ADC | PA02 | Analog noise source |
| Status LED | PA21 | Alarm indicator |
| Buzzer | PA19 | Active buzzer (GPIO on/off) |
| Error LED | PA14 | Error indicator |
| Init LED | PA18 | Initialization indicator |
Architecture
Main Tasks
| Task | Priority | Description |
|---|---|---|
on_eic |
4 | External interrupt handler (LoRa DIO0, door, vibration) |
watchdog_feed |
2 | Periodic watchdog feeding (every 4s) |
process_lora_message |
1 | LoRa message processing (async) |
send_sensor_event |
1 | Door state change event transmission (async) |
install |
1 | Installation message sending (every 10s until validated) |
idle |
- | Main loop with WFI for power saving |
Module Structure
src/
├── main.rs # Main application and RTIC tasks
├── (moved) # Business-logic config/state live in `contact_sensor`
├── device_id/ # Device UID reading (safe wrapper)
│ └── mod.rs
├── helpers/ # Helper modules
│ ├── alarm/ # Alarm control (LED/buzzer)
│ ├── lora/ # LoRa message handling
│ └── timeout/ # Timeout management utilities
├── tasks/ # RTIC tasks
│ └── install/ # Installation message sending
└── types/ # Type definitions
└── mod.rs
Communication Protocol
The system uses the Sigil protocol for encrypted LoRa communication:
- Install messages: Broadcast to all gateways using derived install key
- Validate requests: Uses DEFAULT_KEY for initial validation
- Event messages: Uses validated session key or derived session key
- Encryption: ChaCha20Poly1305 with 12-byte nonces
Note: the firmware no longer depends on hkdf/sha2 directly; ECIES (HKDF-SHA256 + ChaCha20Poly1305)
for the Sigil install handshake is handled inside the sigil crate.
Message Flow
-
Installation:
- Sensor sends
InstallSensorRequestevery 10 seconds for 5 minutes - Continues until gateway responds with validation
- Sensor sends
-
Validation:
- Gateway sends
ValidateRequestusing DEFAULT_KEY - Sensor responds with
ValidateResponsecontaining session key - Session key stored in
current_keywith expiration
- Gateway sends
-
Event Reporting:
- Door state changes trigger
Eventmessages - Uses validated key if available, otherwise derived session key
- Automatic retry on failure (1 retry, 500ms delay)
- Door state changes trigger
Security
Key Management
- Master Key: Stored in
src/config/mod.rs(⚠️ hardcoded for development) - Session Keys: Derived per-communication for enhanced security
- Install Keys: Derived without device_id for gateway compatibility
⚠️ Production Security Notes
- Master key should be loaded from Secure Element (Atecc608x) in production
- Never commit master keys to version control
- Use environment variables or secure storage for keys
- Implement key expiration verification (structure in place, logic pending)
Watchdog Timer
- Timeout: 16 seconds
- Feed interval: Every 4 seconds (4× safety margin)
- Clock: GCLK4 at 1024 Hz (separate from RTC)
- Reset detection: Reads RCAUSE register, lights error LED if watchdog reset
Building and Flashing
Prerequisites
- Rust toolchain (stable or beta)
thumbv6m-none-eabitarget:rustup target add thumbv6m-none-eabi- OpenOCD or J-Link for flashing
Build
# Development build
cargo build --target thumbv6m-none-eabi
# Release build
cargo build --release --target thumbv6m-none-eabi
Flash
./deploy.sh # firmware @ 0x2000 (bootloader slot, default)
./deploy.sh false # firmware @ 0x0 (bare-metal)
./deploy_direct.sh # shortcut for ./deploy.sh false
./deploy_tmp.sh [true|false] # deep_sleep bench
Manual (with bootloader slot):
cargo objcopy --release --bin samd21 --target thumbv6m-none-eabi -- -O binary firmware.bin
openocd -f samd21.cfg -c "init; reset halt; program firmware.bin 0x2000 verify reset; reset run; exit"
Debug (VS Code / Cursor)
- Install extensions: rust-analyzer, Cortex-Debug (see
.vscode/extensions.json). - Connect J-Link (SWD), close any running OpenOCD session.
- Select Debug (OpenOCD) and press F5.
See .vscode/README.md for troubleshooting (missing SVD, OpenOCD on macOS, J-Link fallback).
Testing
See docs/TESTING_WITH_EMBEDDED_HAL_MOCK.md for testing strategy.
Unit Tests
cargo test --target thumbv6m-none-eabi
Validation Script
./scripts/run_tests.sh
Documentation
- Code Review: See
revue.mdfor detailed code analysis and improvements - Interrupt Optimizations: See
OPTIMISATIONS_INTERRUPTIONS.md - Testing Strategy: See
docs/TESTING_WITH_EMBEDDED_HAL_MOCK.md - Pragmatic Testing: See
docs/TESTS_PRAGMATIC_APPROACH.md
Dependencies
atsamd-hal: SAMD21 hardware abstraction layerrtic: Real-Time Interrupt-driven Concurrency frameworkembedded-hal: Hardware abstraction traitssigil: Communication protocol library (local)lora: LoRa SX1278 driver (local)tools: Utility library (local, encryption, random, MAC)
License
[Add your license here]
Contributing
[Add contribution guidelines here]