wii_ext/async_impl/
nunchuk.rs

1use crate::async_impl::interface::{AsyncImplError, InterfaceAsync};
2use crate::core::nunchuk::*;
3use crate::core::ControllerType;
4use embedded_hal_async;
5
6pub struct Nunchuk<I2C, Delay> {
7    interface: InterfaceAsync<I2C, Delay>,
8    calibration: CalibrationData,
9}
10
11impl<I2C, Delay> Nunchuk<I2C, Delay>
12where
13    I2C: embedded_hal_async::i2c::I2c,
14    Delay: embedded_hal_async::delay::DelayNs,
15{
16    /// Create a new Wii Nunchuck
17    pub fn new(i2cdev: I2C, delay: Delay) -> Self {
18        let interface = InterfaceAsync::new(i2cdev, delay);
19        Self {
20            interface,
21            calibration: CalibrationData::default(),
22        }
23    }
24
25    /// Destroy this driver, recovering the i2c bus and delay used to create it
26    pub fn destroy(self) -> (I2C, Delay) {
27        self.interface.destroy()
28    }
29
30    /// Update the stored calibration for this controller
31    ///
32    /// Since each device will have different tolerances, we take a snapshot of some analog data
33    /// to use as the "baseline" center.
34    pub async fn update_calibration(&mut self) -> Result<(), AsyncImplError> {
35        let data = self.read_report().await?;
36        self.calibration = CalibrationData {
37            joystick_x: data.joystick_x,
38            joystick_y: data.joystick_y,
39        };
40        Ok(())
41    }
42
43    /// Send the init sequence to the controller and calibrate it
44    pub async fn init(&mut self) -> Result<(), AsyncImplError> {
45        self.interface.init().await?;
46        self.update_calibration().await?;
47        Ok(())
48    }
49
50    /// poll the controller for the latest data
51    async fn read_report(&mut self) -> Result<NunchukReading, AsyncImplError> {
52        let buf = self.interface.read_ext_report().await?;
53        NunchukReading::from_data(&buf).ok_or(AsyncImplError::InvalidInputData)
54    }
55
56    /// Do a read, and report axis values relative to calibration
57    pub async fn read(&mut self) -> Result<NunchukReadingCalibrated, AsyncImplError> {
58        Ok(NunchukReadingCalibrated::new(
59            self.read_report().await?,
60            &self.calibration,
61        ))
62    }
63
64    /// Determine the controller type based on the type ID of the extension controller
65    pub async fn identify_controller(&mut self) -> Result<Option<ControllerType>, AsyncImplError> {
66        self.interface.identify_controller().await
67    }
68}