#![no_std]
#![forbid(unsafe_code)]
use embassy_time::{Duration, Timer};
use embedded_hal::digital::InputPin;
pub const DEBOUNCE_MS: u64 = 50;
pub const POLL_MS: u64 = 10;
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum TouchState {
Pressed,
Released,
}
#[derive(Debug)]
pub enum TouchError {
ReadError,
SignalUnstable,
}
pub struct Ttp223<P: InputPin> {
pin: P,
last_confirmed_state: bool,
debounce_ms: u64,
poll_ms: u64,
}
impl<P: InputPin> Ttp223<P> {
pub fn new(pin: P) -> Self {
Self {
pin,
last_confirmed_state: false,
debounce_ms: DEBOUNCE_MS,
poll_ms: POLL_MS,
}
}
pub fn new_with_timing(pin: P, debounce_ms: u64, poll_ms: u64) -> Self {
Self {
pin,
last_confirmed_state: false,
debounce_ms,
poll_ms,
}
}
pub async fn wait_for_change(&mut self) -> Result<TouchState, TouchError> {
loop {
let current_raw = self
.pin
.is_high()
.map_err(|_| TouchError::ReadError)?;
if current_raw != self.last_confirmed_state {
Timer::after(Duration::from_millis(self.debounce_ms)).await;
let confirmed = self
.pin
.is_high()
.map_err(|_| TouchError::ReadError)?;
if confirmed == current_raw {
self.last_confirmed_state = confirmed;
return Ok(if confirmed {
TouchState::Pressed
} else {
TouchState::Released
});
}
}
Timer::after(Duration::from_millis(self.poll_ms)).await;
}
}
pub fn get_state(&self) -> TouchState {
if self.last_confirmed_state {
TouchState::Pressed
} else {
TouchState::Released
}
}
pub fn is_pressed(&self) -> bool {
self.last_confirmed_state
}
pub fn release(self) -> P {
self.pin
}
}