1#![forbid(unsafe_code)]
7#![cfg_attr(not(test), no_std)]
8
9
10mod register;
11use embedded_hal as hal;
12use crate::register::Register;
13use core::fmt::Debug;
14use hal::blocking::i2c::{Write, WriteRead};
15
16
17
18#[derive(Clone, Copy)]
19pub enum I2CAddressSwitchState {
21 OnOnOnOn = 0xB0,
23 OffOnOnOn = 0xB2,
25 OnOffOnOn = 0xB4,
27 OffOffOnOn = 0xB6,
29 OnOnOffOn = 0xB8,
31 OffOnOffOn = 0xBA,
33 OnOffOffOn = 0xBC,
35 OffOffOffOn = 0xBE,
37}
38
39impl I2CAddressSwitchState {
40 fn bits(self) -> u8 {
41 self as u8
42 }
43}
44
45#[derive(Clone, Copy)]
46pub enum OperatingMode {
48 Mode0,
53 Mode1,
58
59}
60
61impl OperatingMode {
62
63 pub fn bits(self) -> u8 {
65 self as u8
66 }
67
68 pub fn is_turn_mode(&self) -> bool {
69 match self {
70 OperatingMode::Mode0 | OperatingMode::Mode1 => false,
71 _ => true,
72 }
73 }
74}
75
76pub struct Md22<I2C> {
78 i2c: I2C,
80 mode: u8,
81 address: u8,
82}
83
84impl<I2C, E> Md22<I2C>
85where
86 I2C: WriteRead<Error = E> + Write<Error = E>,
87 E: Debug,
88{
89 pub fn new(i2c: I2C, mode: OperatingMode, address: I2CAddressSwitchState) -> Result<Self, E> {
92 let mut md22 = Md22 {
93 i2c: i2c,
94 mode: mode.bits(),
95 address: address.bits()
96 };
97 md22.set_mode(mode)?;
98 md22.set_acceleration(0)?;
99 md22.set_speed(0)?;
100 md22.set_turn(0)?;
101
102 Ok(md22)
103 }
104
105 pub fn set_mode(&mut self, mode: OperatingMode) -> Result<(), E> {
107 let bytes = [Register::Mode.addr(), mode as u8];
108 self.i2c.write(self.address, &bytes)?;
109 Ok(())
110 }
111
112 pub fn set_speed(&mut self, speed: u8) -> Result<(), E> {
114 let bytes = [Register::Speed.addr(), speed];
115 self.i2c.write(self.address, &bytes)?;
116 Ok(())
117 }
118
119 pub fn set_turn(&mut self, turn: u8) -> Result<(), E> {
121 let bytes = [Register::Turn.addr(), turn];
122 self.i2c.write(self.address, &bytes)?;
123 Ok(())
124 }
125
126 pub fn set_acceleration(&mut self, acceleration: u8) -> Result<(), E> {
129 let bytes = [Register::Acceleration.addr(), acceleration];
130 self.i2c.write(self.address, &bytes)?;
131 Ok(())
132 }
133
134 pub fn get_software_revision(&mut self) -> Result<u8, E> {
135 let bytes = [Register::SoftwareRevision.addr()];
136 let mut buffer: [u8;1] = [0;1];
137 self.i2c.write_read(self.address, &bytes, &mut buffer)?;
138 Ok(buffer[0])
139 }
140}
141
142
143#[cfg(test)]
144mod tests {
145
146
147 use crate::*;
148
149 use embedded_hal_mock as hal;
150
151 #[test]
152 fn get_software_revision() {
153 let address = I2CAddressSwitchState::OnOnOnOn;
154 let expectation = [
155 hal::i2c::Transaction::write(address.bits(), vec![Register::Mode.addr(), 0]),
156 hal::i2c::Transaction::write(address.bits(), vec![Register::Acceleration.addr(), 0]),
157 hal::i2c::Transaction::write(address.bits(), vec![Register::Speed.addr(), 0]),
158 hal::i2c::Transaction::write(address.bits(), vec![Register::Turn.addr(), 0]),
159 hal::i2c::Transaction::write_read(address.bits(), vec![Register::SoftwareRevision.addr()], vec![255]),
160 ];
161 let i2c = hal::i2c::Mock::new(&expectation);
162 let mut md22 = Md22::new(i2c, OperatingMode::Mode0, address).unwrap();
163 assert_eq!(255, md22.get_software_revision().unwrap());
164 }
165
166 #[test]
167 fn set_mode() {
168 let address = I2CAddressSwitchState::OnOnOnOn;
169 let expectation = [
170 hal::i2c::Transaction::write(address.bits(), vec![Register::Mode.addr(), 0]),
171 hal::i2c::Transaction::write(address.bits(), vec![Register::Acceleration.addr(), 0]),
172 hal::i2c::Transaction::write(address.bits(), vec![Register::Speed.addr(), 0]),
173 hal::i2c::Transaction::write(address.bits(), vec![Register::Turn.addr(), 0]),
174 hal::i2c::Transaction::write(address.bits(), vec![Register::Mode.addr(), OperatingMode::Mode1.bits()]),
175 ];
176 let i2c = hal::i2c::Mock::new(&expectation);
177 let mut md22 = Md22::new(i2c, OperatingMode::Mode0, address).unwrap();
178 md22.set_mode(OperatingMode::Mode1).unwrap();
179 }
180
181 #[test]
182 fn set_acceleration() {
183 let address = I2CAddressSwitchState::OnOnOnOn;
184 let expectation = [
185 hal::i2c::Transaction::write(address.bits(), vec![Register::Mode.addr(), 0]),
186 hal::i2c::Transaction::write(address.bits(), vec![Register::Acceleration.addr(), 0]),
187 hal::i2c::Transaction::write(address.bits(), vec![Register::Speed.addr(), 0]),
188 hal::i2c::Transaction::write(address.bits(), vec![Register::Turn.addr(), 0]),
189 hal::i2c::Transaction::write(address.bits(), vec![Register::Acceleration.addr(), 255]),
190 ];
191 let i2c = hal::i2c::Mock::new(&expectation);
192 let mut md22 = Md22::new(i2c, OperatingMode::Mode0, address).unwrap();
193 md22.set_acceleration(255).unwrap();
194 }
195
196 #[test]
197 fn set_speed() {
198 let address = I2CAddressSwitchState::OnOnOnOn;
199 let expectation = [
200 hal::i2c::Transaction::write(address.bits(), vec![Register::Mode.addr(), 0]),
201 hal::i2c::Transaction::write(address.bits(), vec![Register::Acceleration.addr(), 0]),
202 hal::i2c::Transaction::write(address.bits(), vec![Register::Speed.addr(), 0]),
203 hal::i2c::Transaction::write(address.bits(), vec![Register::Turn.addr(), 0]),
204 hal::i2c::Transaction::write(address.bits(), vec![Register::Speed.addr(), 255]),
205 ];
206 let i2c = hal::i2c::Mock::new(&expectation);
207 let mut md22 = Md22::new(i2c, OperatingMode::Mode0, address).unwrap();
208 md22.set_speed(255).unwrap();
209 }
210
211 #[test]
212 fn set_turn() {
213 let address = I2CAddressSwitchState::OnOnOnOn;
214 let expectation = [
215 hal::i2c::Transaction::write(address.bits(), vec![Register::Mode.addr(), 0]),
216 hal::i2c::Transaction::write(address.bits(), vec![Register::Acceleration.addr(), 0]),
217 hal::i2c::Transaction::write(address.bits(), vec![Register::Speed.addr(), 0]),
218 hal::i2c::Transaction::write(address.bits(), vec![Register::Turn.addr(), 0]),
219 hal::i2c::Transaction::write(address.bits(), vec![Register::Turn.addr(), 255]),
220 ];
221 let i2c = hal::i2c::Mock::new(&expectation);
222 let mut md22 = Md22::new(i2c, OperatingMode::Mode0, address).unwrap();
223 md22.set_turn(255).unwrap();
224 }
225}