From 976316ab469992c398706c253c09ee24d14d39cd Mon Sep 17 00:00:00 2001 From: 9names <60134748+9names@users.noreply.github.com> Date: Sun, 14 Apr 2024 12:15:55 +1000 Subject: [PATCH] Move Delay into struct instead of taking by ref (#8) * Store delay in classic-sync struct * Fix tests --- examples/rp2040-hal-blocking/src/main.rs | 12 ++--- wii-ext/src/classic_sync.rs | 60 +++++++++++------------- wii-ext/tests/classic_hd.rs | 8 ++-- wii-ext/tests/classic_pdp_clone.rs | 30 ++++++------ wii-ext/tests/classic_pdp_clone_hd.rs | 8 ++-- wii-ext/tests/classic_pro.rs | 30 ++++++------ wii-ext/tests/classic_pro_hd.rs | 8 ++-- wii-ext/tests/classic_regular.rs | 30 ++++++------ 8 files changed, 91 insertions(+), 95 deletions(-) diff --git a/examples/rp2040-hal-blocking/src/main.rs b/examples/rp2040-hal-blocking/src/main.rs index 1f9370b..e60fa2d 100644 --- a/examples/rp2040-hal-blocking/src/main.rs +++ b/examples/rp2040-hal-blocking/src/main.rs @@ -11,10 +11,10 @@ use panic_probe as _; use bsp::hal::{ self, clocks::init_clocks_and_plls, entry, gpio, pac, sio::Sio, watchdog::Watchdog, Timer, }; +use embedded_hal::delay::DelayNs; use fugit::RateExtU32; use rp_pico as bsp; use wii_ext::classic_sync::Classic; -use embedded_hal::delay::DelayNs; #[entry] fn main() -> ! { @@ -59,14 +59,14 @@ fn main() -> ! { ); // Create, initialise and calibrate the controller - let mut controller = Classic::new(i2c, &mut delay).unwrap(); + let mut controller = Classic::new(i2c, delay).unwrap(); let hi_res = false; // Enable hi-resolution mode. This also updates calibration // Don't really need it for this single stick mode. Plus it might make recovery easier... if hi_res { - controller.enable_hires(&mut delay).unwrap(); + controller.enable_hires().unwrap(); } // If you have a Nunchuk controller, use this instead. @@ -76,15 +76,15 @@ fn main() -> ! { delay.delay_ms(10); // Capture the current button and axis values - let input = controller.read_blocking(&mut delay); + let input = controller.read_blocking(); if let Ok(input) = input { // Print inputs from the controller debug!("{:?}", input); } else { // re-init controller on failure - let _ = controller.init(&mut delay); + let _ = controller.init(); if hi_res { - let _ = controller.enable_hires(&mut delay); + let _ = controller.enable_hires(); } } } diff --git a/wii-ext/src/classic_sync.rs b/wii-ext/src/classic_sync.rs index 9306875..e4fa5b2 100644 --- a/wii-ext/src/classic_sync.rs +++ b/wii-ext/src/classic_sync.rs @@ -17,7 +17,6 @@ use crate::ExtHdReport; use crate::ExtReport; use crate::EXT_I2C_ADDR; use crate::INTERMESSAGE_DELAY_MICROSEC_U32 as INTERMESSAGE_DELAY_MICROSEC; -use embedded_hal::delay::DelayNs; use embedded_hal::i2c::I2c; #[cfg(feature = "defmt_print")] @@ -41,29 +40,32 @@ pub enum Error { InvalidInputData, } -pub struct Classic { +pub struct Classic { i2cdev: I2C, hires: bool, calibration: CalibrationData, + delay: DELAY, } // use crate::nunchuk; -impl Classic +impl Classic where T: I2c, + DELAY: embedded_hal::delay::DelayNs, { /// Create a new Wii Nunchuck /// /// This method will open the provide i2c device file and will /// send the required init sequence in order to read data in /// the future. - pub fn new(i2cdev: T, delay: &mut D) -> Result, Error> { + pub fn new(i2cdev: T, delay: DELAY) -> Result, Error> { let mut classic = Classic { i2cdev, hires: false, calibration: CalibrationData::default(), + delay, }; - classic.init(delay)?; + classic.init()?; Ok(classic) } @@ -71,8 +73,8 @@ where /// /// Since each device will have different tolerances, we take a snapshot of some analog data /// to use as the "baseline" center. - pub fn update_calibration(&mut self, delay: &mut D) -> Result<(), Error> { - let data = self.read_report_blocking(delay)?; + pub fn update_calibration(&mut self) -> Result<(), Error> { + let data = self.read_report_blocking()?; self.calibration = CalibrationData { joystick_left_x: data.joystick_left_x, @@ -127,22 +129,22 @@ where /// Send the init sequence to the Wii extension controller /// /// This could be a bit faster with DelayNs, but since you only init once we'll re-use delay_ms - pub fn init(&mut self, delay: &mut D) -> Result<(), Error> { + pub fn init(&mut self) -> Result<(), Error> { // Extension controllers by default will use encrypted communication, as that is what the Wii does. // We can disable this encryption by writing some magic values // This is described at https://wiibrew.org/wiki/Wiimote/Extension_Controllers#The_New_Way // Reset to base register first - this should recover a controller in a weird state. // Use longer delays here than normal reads - the system seems more unreliable performing these commands - delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); + self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); self.set_read_register_address(0)?; - delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); + self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); self.set_register(0xF0, 0x55)?; - delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); + self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); self.set_register(0xFB, 0x00)?; - delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); - self.update_calibration(delay)?; - delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); + self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); + self.update_calibration()?; + self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); Ok(()) } @@ -151,12 +153,12 @@ where /// This enables the controllers high-resolution report data mode, which returns each /// analogue axis as a u8, rather than packing smaller integers in a structure. /// If your controllers supports this mode, you should use it. It is much better. - pub fn enable_hires(&mut self, delay: &mut D) -> Result<(), Error> { - delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); + pub fn enable_hires(&mut self) -> Result<(), Error> { + self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); self.set_register(0xFE, 0x03)?; - delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); + self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); self.hires = true; - self.update_calibration(delay)?; + self.update_calibration()?; Ok(()) } @@ -169,12 +171,12 @@ where /// This function does not work. /// TODO: work out why, make it public when it works #[allow(dead_code)] - fn disable_hires(&mut self, delay: &mut D) -> Result<(), Error> { - delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); + fn disable_hires(&mut self) -> Result<(), Error> { + self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); self.set_register(0xFE, 0x01)?; - delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); + self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2); self.hires = false; - self.update_calibration(delay)?; + self.update_calibration()?; Ok(()) } @@ -213,22 +215,16 @@ where } /// Simple blocking read helper that will start a sample, wait 10ms, then read the value - pub fn read_report_blocking( - &mut self, - delay: &mut D, - ) -> Result> { + pub fn read_report_blocking(&mut self) -> Result> { self.start_sample()?; - delay.delay_us(INTERMESSAGE_DELAY_MICROSEC); + self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC); self.read_classic_report() } /// Do a read, and report axis values relative to calibration - pub fn read_blocking( - &mut self, - delay: &mut D, - ) -> Result> { + pub fn read_blocking(&mut self) -> Result> { Ok(ClassicReadingCalibrated::new( - self.read_report_blocking(delay)?, + self.read_report_blocking()?, &self.calibration, )) } diff --git a/wii-ext/tests/classic_hd.rs b/wii-ext/tests/classic_hd.rs index 92912be..21a8556 100644 --- a/wii-ext/tests/classic_hd.rs +++ b/wii-ext/tests/classic_hd.rs @@ -46,10 +46,10 @@ macro_rules! assert_joystick_hd { Transaction::read(EXT_I2C_ADDR as u8, test_data::$y.to_vec()), ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - classic.enable_hires(&mut delay).unwrap(); - let input = classic.read_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + classic.enable_hires().unwrap(); + let input = classic.read_blocking().unwrap(); assert!( ($lxl..=$lxh).contains(&input.joystick_left_x), diff --git a/wii-ext/tests/classic_pdp_clone.rs b/wii-ext/tests/classic_pdp_clone.rs index 4d375c7..b609fd5 100644 --- a/wii-ext/tests/classic_pdp_clone.rs +++ b/wii-ext/tests/classic_pdp_clone.rs @@ -51,9 +51,9 @@ fn classic_idle() { ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - let report = classic.read_report_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + let report = classic.read_report_blocking().unwrap(); assert_digital_eq(report, ClassicReading::default()); i2c.done(); } @@ -99,9 +99,9 @@ macro_rules! assert_button_fn { Transaction::read(EXT_I2C_ADDR as u8, $y.to_vec()), ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - let input = classic.read_report_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + let input = classic.read_report_blocking().unwrap(); assert_digital_eq(input, ClassicReading { $x: true, ..Default::default() @@ -146,9 +146,9 @@ fn classic_calibrated_idle() { Transaction::read(EXT_I2C_ADDR as u8, test_data::PDP_LINK_IDLE.to_vec()), ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - let input = classic.read_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + let input = classic.read_blocking().unwrap(); assert_eq!(input.joystick_left_x, 0); assert_eq!(input.joystick_left_y, 0); assert_eq!(input.joystick_right_x, 0); @@ -173,9 +173,9 @@ fn classic_calibrated_joy_left() { Transaction::read(EXT_I2C_ADDR as u8, test_data::PDP_LINK_LJOY_L.to_vec()), ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - let input = classic.read_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + let input = classic.read_blocking().unwrap(); assert!( (i8::MIN..-AXIS_MAX).contains(&input.joystick_left_x), @@ -236,9 +236,9 @@ macro_rules! assert_joysticks { Transaction::read(EXT_I2C_ADDR as u8, test_data::$y.to_vec()), ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - let input = classic.read_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + let input = classic.read_blocking().unwrap(); assert!( ($lxl..=$lxh).contains(&input.joystick_left_x), diff --git a/wii-ext/tests/classic_pdp_clone_hd.rs b/wii-ext/tests/classic_pdp_clone_hd.rs index dc8fbf4..0094c3c 100644 --- a/wii-ext/tests/classic_pdp_clone_hd.rs +++ b/wii-ext/tests/classic_pdp_clone_hd.rs @@ -46,10 +46,10 @@ macro_rules! assert_joystick_hd { Transaction::read(EXT_I2C_ADDR as u8, test_data::$y.to_vec()), ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - classic.enable_hires(&mut delay).unwrap(); - let input = classic.read_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + classic.enable_hires().unwrap(); + let input = classic.read_blocking().unwrap(); assert!( ($lxl..=$lxh).contains(&input.joystick_left_x), diff --git a/wii-ext/tests/classic_pro.rs b/wii-ext/tests/classic_pro.rs index c1bb047..30e212b 100644 --- a/wii-ext/tests/classic_pro.rs +++ b/wii-ext/tests/classic_pro.rs @@ -51,9 +51,9 @@ fn classic_idle() { ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - let report = classic.read_report_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + let report = classic.read_report_blocking().unwrap(); assert_digital_eq(report, ClassicReading::default()); i2c.done(); } @@ -99,9 +99,9 @@ macro_rules! assert_button_fn { Transaction::read(EXT_I2C_ADDR as u8, $y.to_vec()), ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - let input = classic.read_report_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + let input = classic.read_report_blocking().unwrap(); assert_digital_eq(input, ClassicReading { $x: true, ..Default::default() @@ -146,9 +146,9 @@ fn classic_calibrated_idle() { Transaction::read(EXT_I2C_ADDR as u8, test_data::PRO_IDLE.to_vec()), ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - let input = classic.read_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + let input = classic.read_blocking().unwrap(); assert_eq!(input.joystick_left_x, 0); assert_eq!(input.joystick_left_y, 0); assert_eq!(input.joystick_right_x, 0); @@ -173,9 +173,9 @@ fn classic_calibrated_joy_left() { Transaction::read(EXT_I2C_ADDR as u8, test_data::PRO_LJOY_L.to_vec()), ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - let input = classic.read_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + let input = classic.read_blocking().unwrap(); assert!( (i8::MIN..-AXIS_MAX).contains(&input.joystick_left_x), @@ -237,9 +237,9 @@ macro_rules! assert_joysticks { Transaction::read(EXT_I2C_ADDR as u8, test_data::$y.to_vec()), ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - let input = classic.read_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + let input = classic.read_blocking().unwrap(); assert!( ($lxl..=$lxh).contains(&input.joystick_left_x), diff --git a/wii-ext/tests/classic_pro_hd.rs b/wii-ext/tests/classic_pro_hd.rs index 0cb2bbf..8e7efa5 100644 --- a/wii-ext/tests/classic_pro_hd.rs +++ b/wii-ext/tests/classic_pro_hd.rs @@ -46,10 +46,10 @@ macro_rules! assert_joystick_hd { Transaction::read(EXT_I2C_ADDR as u8, test_data::$y.to_vec()), ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - classic.enable_hires(&mut delay).unwrap(); - let input = classic.read_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + classic.enable_hires().unwrap(); + let input = classic.read_blocking().unwrap(); assert!( ($lxl..=$lxh).contains(&input.joystick_left_x), diff --git a/wii-ext/tests/classic_regular.rs b/wii-ext/tests/classic_regular.rs index ba72ff4..40bdd1a 100644 --- a/wii-ext/tests/classic_regular.rs +++ b/wii-ext/tests/classic_regular.rs @@ -49,9 +49,9 @@ fn classic_idle() { ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - let report = classic.read_report_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + let report = classic.read_report_blocking().unwrap(); assert_digital_eq(report, ClassicReading::default()); i2c.done(); } @@ -97,9 +97,9 @@ macro_rules! assert_button_fn { Transaction::read(EXT_I2C_ADDR as u8, $y.to_vec()), ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - let input = classic.read_report_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + let input = classic.read_report_blocking().unwrap(); assert_digital_eq(input, ClassicReading { $x: true, ..Default::default() @@ -144,9 +144,9 @@ fn classic_calibrated_idle() { Transaction::read(EXT_I2C_ADDR as u8, test_data::CLASSIC_IDLE.to_vec()), ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - let input = classic.read_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + let input = classic.read_blocking().unwrap(); assert_eq!(input.joystick_left_x, 0); assert_eq!(input.joystick_left_y, 0); assert_eq!(input.joystick_right_x, 0); @@ -174,9 +174,9 @@ fn classic_calibrated_joy_left() { Transaction::read(EXT_I2C_ADDR as u8, test_data::CLASSIC_LJOY_L.to_vec()), ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - let input = classic.read_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + let input = classic.read_blocking().unwrap(); assert!( (i8::MIN..=-AXIS_MAX).contains(&input.joystick_left_x), @@ -237,9 +237,9 @@ macro_rules! assert_joysticks { Transaction::read(EXT_I2C_ADDR as u8, test_data::$y.to_vec()), ]; let mut i2c = i2c::Mock::new(&expectations); - let mut delay = NoopDelay::new(); - let mut classic = Classic::new(i2c.clone(), &mut delay).unwrap(); - let input = classic.read_blocking(&mut delay).unwrap(); + let delay = NoopDelay::new(); + let mut classic = Classic::new(i2c.clone(), delay).unwrap(); + let input = classic.read_blocking().unwrap(); assert!( ($lxl..=$lxh).contains(&input.joystick_left_x),