use crate::blocking_impl::interface::{BlockingImplError, Interface};
use crate::core::classic::{CalibrationData, ClassicReading, ClassicReadingCalibrated};
use crate::core::ControllerType;
use embedded_hal::i2c::I2c;
#[cfg(feature = "defmt_print")]
use defmt;
use embedded_hal::i2c::SevenBitAddress;
#[cfg_attr(feature = "defmt_print", derive(defmt::Format))]
#[derive(Debug)]
pub enum ClassicError<E> {
Error(E),
ParseError,
}
#[cfg_attr(feature = "defmt_print", derive(defmt::Format))]
#[derive(Debug, Default)]
pub struct Classic<I2C, DELAY> {
interface: Interface<I2C, DELAY>,
hires: bool,
calibration: CalibrationData,
}
impl<T, E, DELAY> Classic<T, DELAY>
where
T: I2c<SevenBitAddress, Error = E>,
DELAY: embedded_hal::delay::DelayNs,
{
pub fn new(i2cdev: T, delay: DELAY) -> Result<Classic<T, DELAY>, BlockingImplError<E>> {
let interface = Interface::new(i2cdev, delay);
let mut classic = Classic {
interface,
hires: false,
calibration: CalibrationData::default(),
};
classic.init()?;
Ok(classic)
}
pub fn destroy(self) -> (T, DELAY) {
self.interface.destroy()
}
pub fn update_calibration(&mut self) -> Result<(), BlockingImplError<E>> {
let data = self.read_uncalibrated()?;
self.calibration = CalibrationData {
joystick_left_x: data.joystick_left_x,
joystick_left_y: data.joystick_left_y,
joystick_right_x: data.joystick_right_x,
joystick_right_y: data.joystick_right_y,
trigger_left: data.trigger_left,
trigger_right: data.trigger_left,
};
Ok(())
}
pub fn init(&mut self) -> Result<(), BlockingImplError<E>> {
self.interface.init()?;
self.update_calibration()?;
Ok(())
}
pub fn enable_hires(&mut self) -> Result<(), BlockingImplError<E>> {
self.interface.enable_hires()?;
self.hires = true;
self.update_calibration()?;
Ok(())
}
#[allow(dead_code)]
fn disable_hires(&mut self) -> Result<(), BlockingImplError<E>> {
self.interface.disable_hires()?;
self.hires = false;
self.update_calibration()?;
Ok(())
}
pub fn identify_controller(&mut self) -> Result<Option<ControllerType>, BlockingImplError<E>> {
self.interface.identify_controller()
}
pub fn read_uncalibrated(&mut self) -> Result<ClassicReading, BlockingImplError<E>> {
self.interface.start_sample_and_wait()?;
if self.hires {
let buf = self.interface.read_hd_report()?;
ClassicReading::from_data(&buf).ok_or(BlockingImplError::InvalidInputData)
} else {
let buf = self.interface.read_report()?;
ClassicReading::from_data(&buf).ok_or(BlockingImplError::InvalidInputData)
}
}
pub fn read(&mut self) -> Result<ClassicReadingCalibrated, BlockingImplError<E>> {
Ok(ClassicReadingCalibrated::new(
self.read_uncalibrated()?,
&self.calibration,
))
}
}