use esp_hal::gpio::AnyPin;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ButtonId {
Left,
Center,
Right,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ButtonAction {
Short(usize),
Long,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ButtonEvent {
pub id: ButtonId,
pub action: ButtonAction,
}
pub struct ButtonResources<'a> {
pub left: AnyPin<'a>,
pub center: AnyPin<'a>,
pub right: AnyPin<'a>,
}
#[cfg(feature = "buttons")]
mod physical {
use async_button::{Button, ButtonConfig, ButtonEvent as AsyncButtonEvent};
use embassy_futures::select::{Either3, select3};
use esp_hal::gpio::{Input, InputConfig, Pull};
use super::{ButtonAction, ButtonEvent, ButtonId, ButtonResources};
impl ButtonResources<'static> {
pub fn into_buttons(self) -> Buttons<'static> {
let make = |pin| {
Button::new(
Input::new(pin, InputConfig::default().with_pull(Pull::Up)),
ButtonConfig::default(),
)
};
Buttons {
left: make(self.left),
center: make(self.center),
right: make(self.right),
}
}
}
pub struct Buttons<'a> {
left: Button<Input<'a>>,
center: Button<Input<'a>>,
right: Button<Input<'a>>,
}
impl Buttons<'_> {
pub async fn next_event(&mut self) -> ButtonEvent {
let (id, event) = match select3(
self.left.update(),
self.center.update(),
self.right.update(),
)
.await
{
Either3::First(e) => (ButtonId::Left, e),
Either3::Second(e) => (ButtonId::Center, e),
Either3::Third(e) => (ButtonId::Right, e),
};
let action = match event {
AsyncButtonEvent::ShortPress { count } => ButtonAction::Short(count),
AsyncButtonEvent::LongPress => ButtonAction::Long,
};
ButtonEvent { id, action }
}
}
}
#[cfg(feature = "buttons")]
pub use physical::Buttons;