use mwatch_kernel_api::InputEvent;
use crate::{LeftButton, MiddleButton, RightButton, TouchSenseController};
use crate::hal::tsc::Event as TscEvent;
pub const LEFT: u8 = 1;
pub const MIDDLE: u8 = 2;
pub const RIGHT: u8 = 4;
pub const LEFT_MIDDLE: u8 = LEFT | MIDDLE;
pub const RIGHT_MIDDLE: u8 = RIGHT | MIDDLE;
pub const LEFT_RIGHT: u8 = LEFT | RIGHT;
pub const ALL: u8 = LEFT | MIDDLE | RIGHT;
pub const NONE: u8 = 0;
const NUM_SAMPLES: u16 = 25;
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Error {
NoInput,
InvalidInputVector(u8),
InvalidInputPin,
AcquisitionInProgress,
Incomplete
}
pub struct InputManager
{
raw_vector: u8,
last_vector: u8,
pin_idx: u8,
tsc_threshold: u16,
tsc: TouchSenseController,
left: LeftButton,
middle: MiddleButton,
right: RightButton,
}
impl InputManager {
pub fn new(tsc: TouchSenseController, left: LeftButton, middle: MiddleButton, right: RightButton) -> Self {
let mut left = left;
let mut tsc = tsc;
let mut baseline = 0;
for _ in 0..NUM_SAMPLES {
baseline += tsc.acquire(&mut left).unwrap();
}
let threshold = ((baseline / NUM_SAMPLES) / 100) * 152;
tsc.listen(TscEvent::EndOfAcquisition);
Self {
tsc: tsc,
tsc_threshold: threshold,
raw_vector: 0,
last_vector: 0,
pin_idx: 0,
left: left,
middle: middle,
right: right,
}
}
pub fn update_input(&mut self, active: bool) {
if active {
self.raw_vector |= match self.pin_idx {
0 => 1 << 0,
1 => 1 << 1,
2 => 1 << 2,
_ => panic!("Invalid pin index")
};
} else {
self.raw_vector &= match self.pin_idx {
0 => !(1 << 0),
1 => !(1 << 1),
2 => !(1 << 2),
_ => panic!("Invalid pin index")
};
}
self.pin_idx += 1;
if self.pin_idx > 2 {
self.pin_idx = 0;
}
}
pub fn output(&mut self) -> Result<InputEvent, Error> {
if self.raw_vector != self.last_vector {
let result = match self.raw_vector {
ALL => Ok(InputEvent::Multi),
LEFT_RIGHT => Ok(InputEvent::Dual),
LEFT_MIDDLE => Ok(InputEvent::LeftMiddle),
RIGHT_MIDDLE => Ok(InputEvent::RightMiddle),
LEFT => Ok(InputEvent::Left),
MIDDLE => Ok(InputEvent::Middle),
RIGHT => Ok(InputEvent::Right),
NONE => Err(Error::NoInput), _ => Err(Error::InvalidInputVector(self.raw_vector)),
};
self.last_vector = self.raw_vector;
result
} else {
Err(Error::NoInput)
}
}
pub fn start_new(&mut self) -> Result<(), Error> {
if self.tsc.in_progress() {
return Err(Error::AcquisitionInProgress);
}
match self.pin_idx {
0 => self.tsc.start(&mut self.left),
1 => self.tsc.start(&mut self.middle),
2 => self.tsc.start(&mut self.right),
_ => panic!("Invalid pin index")
}
Ok(())
}
pub fn process_result(&mut self) -> Result<(), Error> {
let value = match self.pin_idx {
0 => self.tsc.read(&mut self.left).unwrap(),
1 => self.tsc.read(&mut self.middle).unwrap(),
2 => self.tsc.read(&mut self.right).unwrap(),
_ => panic!("Invalid pin index")
};
trace!("tsc[{}] {} < {}?", self.pin_idx, value, self.tsc_threshold);
self.update_input(value < self.tsc_threshold);
self.tsc.clear(TscEvent::EndOfAcquisition);
if self.pin_idx == 2 { Ok(())
} else {
Err(Error::Incomplete)
}
}
}