wii_ext/blocking_impl/
interface.rs1use crate::core::{
2 ControllerIdReport, ControllerType, ExtHdReport, ExtReport, EXT_I2C_ADDR,
3 INTERMESSAGE_DELAY_MICROSEC_U32 as INTERMESSAGE_DELAY_MICROSEC,
4};
5use embedded_hal::i2c::{I2c, SevenBitAddress};
6
7#[cfg_attr(feature = "defmt_print", derive(defmt::Format))]
8#[derive(Debug, Default)]
9pub struct Interface<I2C, Delay> {
10 i2cdev: I2C,
11 delay: Delay,
12}
13
14#[cfg_attr(feature = "defmt_print", derive(defmt::Format))]
15#[derive(Debug)]
16pub enum BlockingImplError<E> {
18 I2C(E),
20 InvalidInputData,
22}
23
24impl<I2C, E, Delay> Interface<I2C, Delay>
25where
26 I2C: I2c<SevenBitAddress, Error = E>,
27 Delay: embedded_hal::delay::DelayNs,
28{
29 pub fn new(i2cdev: I2C, delay: Delay) -> Interface<I2C, Delay> {
30 Interface { i2cdev, delay }
31 }
32
33 pub fn destroy(self) -> (I2C, Delay) {
35 (self.i2cdev, self.delay)
36 }
37
38 pub(super) fn init(&mut self) -> Result<(), BlockingImplError<E>> {
40 self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2);
47 self.set_read_register_address(0)?;
48 self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2);
49 self.set_register(0xF0, 0x55)?;
50 self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2);
51 self.set_register(0xFB, 0x00)?;
52 self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2);
53 Ok(())
54 }
55
56 pub(super) fn read_id(&mut self) -> Result<ControllerIdReport, BlockingImplError<E>> {
57 self.set_read_register_address(0xfa)?;
58 let i2c_id = self.read_report()?;
59 Ok(i2c_id)
60 }
61
62 pub(super) fn identify_controller(
64 &mut self,
65 ) -> Result<Option<ControllerType>, BlockingImplError<E>> {
66 let i2c_id = self.read_id()?;
67 Ok(crate::core::identify_controller(i2c_id))
68 }
69
70 pub(super) fn start_sample(&mut self) -> Result<(), BlockingImplError<E>> {
72 self.set_read_register_address(0x00)?;
73 Ok(())
74 }
75
76 pub(super) fn start_sample_and_wait(&mut self) -> Result<(), BlockingImplError<E>> {
78 self.set_read_register_address(0x00)?;
79 self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC);
80 Ok(())
81 }
82
83 pub(super) fn set_read_register_address(
90 &mut self,
91 byte0: u8,
92 ) -> Result<(), BlockingImplError<E>> {
93 self.i2cdev
94 .write(EXT_I2C_ADDR as u8, &[byte0])
95 .map_err(BlockingImplError::I2C)
96 .and(Ok(()))
97 }
98
99 pub(super) fn set_register(&mut self, addr: u8, byte1: u8) -> Result<(), BlockingImplError<E>> {
101 self.i2cdev
102 .write(EXT_I2C_ADDR as u8, &[addr, byte1])
103 .map_err(BlockingImplError::I2C)
104 .and(Ok(()))
105 }
106
107 pub(super) fn read_report(&mut self) -> Result<ExtReport, BlockingImplError<E>> {
109 let mut buffer: ExtReport = ExtReport::default();
110 self.i2cdev
111 .read(EXT_I2C_ADDR as u8, &mut buffer)
112 .map_err(BlockingImplError::I2C)
113 .and(Ok(buffer))
114 }
115
116 pub(super) fn enable_hires(&mut self) -> Result<(), BlockingImplError<E>> {
117 self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2);
118 self.set_register(0xFE, 0x03)?;
119 self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2);
120 Ok(())
121 }
122
123 pub(super) fn disable_hires(&mut self) -> Result<(), BlockingImplError<E>> {
124 self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2);
125 self.set_register(0xFE, 0x01)?;
126 self.delay.delay_us(INTERMESSAGE_DELAY_MICROSEC * 2);
127 Ok(())
128 }
129
130 pub(super) fn read_hd_report(&mut self) -> Result<ExtHdReport, BlockingImplError<E>> {
132 let mut buffer: ExtHdReport = ExtHdReport::default();
133 self.i2cdev
134 .read(EXT_I2C_ADDR as u8, &mut buffer)
135 .map_err(BlockingImplError::I2C)
136 .and(Ok(buffer))
137 }
138}