use crate::blocking_impl::interface::{BlockingImplError, Interface};
use crate::core::nunchuk::{CalibrationData, NunchukReading, NunchukReadingCalibrated};
use crate::core::ControllerType;
use embedded_hal::i2c::{I2c, SevenBitAddress};
#[derive(Debug)]
pub enum NunchukError<E> {
Error(E),
ParseError,
}
pub struct Nunchuk<I2C, DELAY> {
interface: Interface<I2C, DELAY>,
calibration: CalibrationData,
}
impl<I2C, ERR, DELAY> Nunchuk<I2C, DELAY>
where
I2C: I2c<SevenBitAddress, Error = ERR>,
DELAY: embedded_hal::delay::DelayNs,
{
pub fn new(i2cdev: I2C, delay: DELAY) -> Result<Nunchuk<I2C, DELAY>, BlockingImplError<ERR>> {
let interface = Interface::new(i2cdev, delay);
let mut nunchuk = Nunchuk {
interface,
calibration: CalibrationData::default(),
};
nunchuk.init()?;
Ok(nunchuk)
}
pub fn destroy(self) -> (I2C, DELAY) {
self.interface.destroy()
}
pub fn update_calibration(&mut self) -> Result<(), BlockingImplError<ERR>> {
let data = self.read_uncalibrated()?;
self.calibration = CalibrationData {
joystick_x: data.joystick_x,
joystick_y: data.joystick_y,
};
Ok(())
}
pub fn init(&mut self) -> Result<(), BlockingImplError<ERR>> {
self.interface.init()?;
self.update_calibration()
}
pub fn identify_controller(
&mut self,
) -> Result<Option<ControllerType>, BlockingImplError<ERR>> {
self.interface.identify_controller()
}
pub fn read_uncalibrated(&mut self) -> Result<NunchukReading, BlockingImplError<ERR>> {
self.interface.start_sample()?;
let buf = self.interface.read_report()?;
NunchukReading::from_data(&buf).ok_or(BlockingImplError::InvalidInputData)
}
pub fn read(&mut self) -> Result<NunchukReadingCalibrated, BlockingImplError<ERR>> {
Ok(NunchukReadingCalibrated::new(
self.read_uncalibrated()?,
&self.calibration,
))
}
}