handle button press to enable/disable blinking
This commit is contained in:
parent
db4adc53fa
commit
530ea9a0e5
4 changed files with 142 additions and 16 deletions
39
Cargo.lock
generated
39
Cargo.lock
generated
|
@ -229,6 +229,7 @@ dependencies = [
|
||||||
"defmt-rtt",
|
"defmt-rtt",
|
||||||
"embassy-executor",
|
"embassy-executor",
|
||||||
"embassy-stm32",
|
"embassy-stm32",
|
||||||
|
"embassy-sync 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"embassy-time 0.1.3",
|
"embassy-time 0.1.3",
|
||||||
"panic-probe",
|
"panic-probe",
|
||||||
]
|
]
|
||||||
|
@ -240,7 +241,7 @@ source = "git+https://github.com/embassy-rs/embassy#42176b1a3addde3a6daad0662d36
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"defmt",
|
"defmt",
|
||||||
"embassy-futures",
|
"embassy-futures",
|
||||||
"embassy-sync",
|
"embassy-sync 0.3.0 (git+https://github.com/embassy-rs/embassy)",
|
||||||
"embassy-time 0.1.4",
|
"embassy-time 0.1.4",
|
||||||
"embedded-hal 0.2.7",
|
"embedded-hal 0.2.7",
|
||||||
"embedded-hal 1.0.0-rc.1",
|
"embedded-hal 1.0.0-rc.1",
|
||||||
|
@ -320,14 +321,14 @@ dependencies = [
|
||||||
"embassy-futures",
|
"embassy-futures",
|
||||||
"embassy-hal-internal",
|
"embassy-hal-internal",
|
||||||
"embassy-net-driver",
|
"embassy-net-driver",
|
||||||
"embassy-sync",
|
"embassy-sync 0.3.0 (git+https://github.com/embassy-rs/embassy)",
|
||||||
"embassy-time 0.1.4",
|
"embassy-time 0.1.4",
|
||||||
"embassy-usb-driver",
|
"embassy-usb-driver",
|
||||||
"embedded-hal 0.2.7",
|
"embedded-hal 0.2.7",
|
||||||
"embedded-hal 1.0.0-rc.1",
|
"embedded-hal 1.0.0-rc.1",
|
||||||
"embedded-hal-async",
|
"embedded-hal-async",
|
||||||
"embedded-io",
|
"embedded-io 0.6.0",
|
||||||
"embedded-io-async",
|
"embedded-io-async 0.6.0",
|
||||||
"embedded-storage",
|
"embedded-storage",
|
||||||
"embedded-storage-async",
|
"embedded-storage-async",
|
||||||
"futures",
|
"futures",
|
||||||
|
@ -342,6 +343,19 @@ dependencies = [
|
||||||
"vcell",
|
"vcell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embassy-sync"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0525b466ca3ace30b57f2db868a35215dfaecd038d8668cb2db03feb7c069a0"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"critical-section 1.1.2",
|
||||||
|
"embedded-io-async 0.5.0",
|
||||||
|
"futures-util",
|
||||||
|
"heapless",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "embassy-sync"
|
name = "embassy-sync"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
@ -417,6 +431,12 @@ dependencies = [
|
||||||
"embedded-hal 1.0.0-rc.1",
|
"embedded-hal 1.0.0-rc.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-io"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "658bbadc628dc286b9ae02f0cb0f5411c056eb7487b72f0083203f115de94060"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "embedded-io"
|
name = "embedded-io"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
|
@ -426,6 +446,15 @@ dependencies = [
|
||||||
"defmt",
|
"defmt",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-io-async"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1394754ad749a560b25a0c70dcd2b66a450824a1311fc475bb2ccbfabe7f8414"
|
||||||
|
dependencies = [
|
||||||
|
"embedded-io 0.5.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "embedded-io-async"
|
name = "embedded-io-async"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
|
@ -433,7 +462,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "de03527d6fb488b2d7c7a4dc81dfb6a657efe264256bfc70bb899746821666b1"
|
checksum = "de03527d6fb488b2d7c7a4dc81dfb6a657efe264256bfc70bb899746821666b1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"defmt",
|
"defmt",
|
||||||
"embedded-io",
|
"embedded-io 0.6.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -10,6 +10,7 @@ defmt = "0.3"
|
||||||
defmt-rtt = "0.3"
|
defmt-rtt = "0.3"
|
||||||
# potentially use executor-interrupt instead of executor-thread for cortex-m architectures
|
# potentially use executor-interrupt instead of executor-thread for cortex-m architectures
|
||||||
embassy-executor = { version = "0.3", features = ["defmt", "integrated-timers", "arch-cortex-m", "executor-thread", "nightly"] }
|
embassy-executor = { version = "0.3", features = ["defmt", "integrated-timers", "arch-cortex-m", "executor-thread", "nightly"] }
|
||||||
embassy-stm32 = { git = "https://github.com/embassy-rs/embassy", features = ["defmt", "time", "time-driver-tim2", "stm32l476rg", "nightly"] }
|
embassy-stm32 = { git = "https://github.com/embassy-rs/embassy", features = ["defmt", "exti", "time", "time-driver-tim2", "stm32l476rg", "nightly"] }
|
||||||
|
embassy-sync = { version = "0.3", features = ["nightly"] }
|
||||||
embassy-time = { version = "0.1.3", features = ["defmt", "nightly"] }
|
embassy-time = { version = "0.1.3", features = ["defmt", "nightly"] }
|
||||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
||||||
|
|
55
src/main.rs
55
src/main.rs
|
@ -1,31 +1,66 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(async_fn_track_caller, type_alias_impl_trait)]
|
||||||
|
#![warn(rust_2018_idioms)]
|
||||||
|
#![forbid(elided_lifetimes_in_paths, unsafe_code)]
|
||||||
|
|
||||||
|
mod static_mutex;
|
||||||
|
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use defmt_rtt as _;
|
use defmt_rtt as _;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_stm32::{
|
use embassy_stm32::{
|
||||||
gpio::{Level, Output, Speed},
|
exti::ExtiInput,
|
||||||
peripherals::PA5
|
gpio::{Input, Level, Output, Pull, Speed},
|
||||||
|
peripherals::{PA5, PC13}
|
||||||
};
|
};
|
||||||
|
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use panic_probe as _; // global logger
|
use panic_probe as _;
|
||||||
|
use static_mutex::StaticMutex;
|
||||||
|
|
||||||
|
type Mutex<T> = embassy_sync::mutex::Mutex<ThreadModeRawMutex, T>;
|
||||||
|
type MutexGuard<'a, T> = embassy_sync::mutex::MutexGuard<'a, ThreadModeRawMutex, T>;
|
||||||
|
|
||||||
|
type NucleoLed = Output<'static, PA5>;
|
||||||
|
type NucleoButton = ExtiInput<'static, PC13>;
|
||||||
|
|
||||||
|
static LED: StaticMutex<NucleoLed> = StaticMutex::new();
|
||||||
|
static BLINKING: Mutex<bool> = Mutex::new(true);
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn blinker(mut led: Output<'static, PA5>, interval: Duration) {
|
async fn blinker(interval: Duration) {
|
||||||
loop {
|
loop {
|
||||||
led.set_high();
|
if *BLINKING.lock().await {
|
||||||
Timer::after(interval).await;
|
LED.lock().await.toggle();
|
||||||
led.set_low();
|
}
|
||||||
Timer::after(interval).await;
|
Timer::after(interval).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[embassy_executor::task]
|
||||||
|
async fn button_handler(mut button: NucleoButton) {
|
||||||
|
loop {
|
||||||
|
button.wait_for_falling_edge().await;
|
||||||
|
let mut blinking = BLINKING.lock().await;
|
||||||
|
if *blinking {
|
||||||
|
info!("Disable blinking");
|
||||||
|
LED.lock().await.set_low();
|
||||||
|
*blinking = false;
|
||||||
|
} else {
|
||||||
|
info!("Enable blinking");
|
||||||
|
*blinking = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(spawner: Spawner) {
|
async fn main(spawner: Spawner) {
|
||||||
let p = embassy_stm32::init(Default::default());
|
let p = embassy_stm32::init(Default::default());
|
||||||
|
|
||||||
let led = Output::new(p.PA5, Level::Low, Speed::Low);
|
LED.init(Output::new(p.PA5, Level::Low, Speed::Low)).await;
|
||||||
unwrap!(spawner.spawn(blinker(led, Duration::from_millis(500))));
|
let button = ExtiInput::new(Input::new(p.PC13, Pull::Up), p.EXTI13);
|
||||||
|
|
||||||
|
unwrap!(spawner.spawn(blinker(Duration::from_millis(500))));
|
||||||
|
unwrap!(spawner.spawn(button_handler(button)));
|
||||||
}
|
}
|
||||||
|
|
61
src/static_mutex.rs
Normal file
61
src/static_mutex.rs
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
use crate::{Mutex, MutexGuard};
|
||||||
|
use core::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
|
enum Value<T> {
|
||||||
|
Full(T),
|
||||||
|
Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct StaticMutex<T> {
|
||||||
|
value: Mutex<Value<T>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> StaticMutex<T> {
|
||||||
|
pub const fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
value: Mutex::new(Value::Empty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
pub async fn init(&self, new: T) {
|
||||||
|
let mut value = self.value.lock().await;
|
||||||
|
if !matches!(*value, Value::Empty) {
|
||||||
|
panic!("Cannot initialise StaticMutex more than once");
|
||||||
|
}
|
||||||
|
*value = Value::Full(new);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
pub async fn lock(&self) -> StaticMutexLockGuard<'_, T> {
|
||||||
|
let inner = self.value.lock().await;
|
||||||
|
if matches!(*inner, Value::Empty) {
|
||||||
|
panic!("This StaticMutex has not been initialised yet");
|
||||||
|
}
|
||||||
|
StaticMutexLockGuard { inner }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct StaticMutexLockGuard<'a, T> {
|
||||||
|
inner: MutexGuard<'a, Value<T>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Deref for StaticMutexLockGuard<'_, T> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
match self.inner.deref() {
|
||||||
|
Value::Full(ref value) => value,
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> DerefMut for StaticMutexLockGuard<'_, T> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
match self.inner.deref_mut() {
|
||||||
|
Value::Full(ref mut value) => value,
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue