1pub use rtc_hal::control::RtcPowerControl;
29
30use crate::{
31 Ds3231,
32 registers::{EOSC_BIT, Register},
33};
34
35impl<I2C> RtcPowerControl for Ds3231<I2C>
36where
37 I2C: embedded_hal::i2c::I2c,
38{
39 fn start_clock(&mut self) -> Result<(), Self::Error> {
46 self.clear_register_bits(Register::Control, EOSC_BIT)
47 }
48
49 fn halt_clock(&mut self) -> Result<(), Self::Error> {
57 self.set_register_bits(Register::Control, EOSC_BIT)
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64 use crate::registers::{EOSC_BIT, Register};
65 use embedded_hal_mock::eh1::i2c::{Mock as I2cMock, Transaction as I2cTransaction};
66 use rtc_hal::control::RtcPowerControl;
67
68 const DS3231_ADDR: u8 = 0x68;
69
70 #[test]
71 fn test_start_clock_sets_eosc_bit_to_zero() {
72 let expectations = vec![
73 I2cTransaction::write_read(
75 DS3231_ADDR,
76 vec![Register::Control.addr()],
77 vec![EOSC_BIT], ),
79 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0000_0000]),
81 ];
82
83 let mut i2c_mock = I2cMock::new(&expectations);
84 let mut ds3231 = Ds3231::new(&mut i2c_mock);
85
86 let result = ds3231.start_clock();
87 assert!(result.is_ok());
88
89 i2c_mock.done();
90 }
91
92 #[test]
93 fn test_start_clock_already_running() {
94 let expectations = vec![
95 I2cTransaction::write_read(
97 DS3231_ADDR,
98 vec![Register::Control.addr()],
99 vec![0b0000_0000], ),
101 ];
103
104 let mut i2c_mock = I2cMock::new(&expectations);
105 let mut ds3231 = Ds3231::new(&mut i2c_mock);
106
107 let result = ds3231.start_clock();
108 assert!(result.is_ok());
109
110 i2c_mock.done();
111 }
112
113 #[test]
114 fn test_start_clock_preserves_other_bits() {
115 let expectations = vec![
116 I2cTransaction::write_read(
118 DS3231_ADDR,
119 vec![Register::Control.addr()],
120 vec![0b0100_0101 | EOSC_BIT], ),
122 I2cTransaction::write(
124 DS3231_ADDR,
125 vec![Register::Control.addr(), 0b0100_0101], ),
127 ];
128
129 let mut i2c_mock = I2cMock::new(&expectations);
130 let mut ds3231 = Ds3231::new(&mut i2c_mock);
131
132 let result = ds3231.start_clock();
133 assert!(result.is_ok());
134
135 i2c_mock.done();
136 }
137
138 #[test]
139 fn test_halt_clock_sets_eosc_bit_to_one() {
140 let expectations = vec![
141 I2cTransaction::write_read(
143 DS3231_ADDR,
144 vec![Register::Control.addr()],
145 vec![0b0000_0000], ),
147 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), EOSC_BIT]),
149 ];
150
151 let mut i2c_mock = I2cMock::new(&expectations);
152 let mut ds3231 = Ds3231::new(&mut i2c_mock);
153
154 let result = ds3231.halt_clock();
155 assert!(result.is_ok());
156
157 i2c_mock.done();
158 }
159
160 #[test]
161 fn test_halt_clock_already_halted() {
162 let expectations = vec![
163 I2cTransaction::write_read(
165 DS3231_ADDR,
166 vec![Register::Control.addr()],
167 vec![EOSC_BIT], ),
169 ];
171
172 let mut i2c_mock = I2cMock::new(&expectations);
173 let mut ds3231 = Ds3231::new(&mut i2c_mock);
174
175 let result = ds3231.halt_clock();
176 assert!(result.is_ok());
177
178 i2c_mock.done();
179 }
180
181 #[test]
182 fn test_halt_clock_preserves_other_bits() {
183 let expectations = vec![
184 I2cTransaction::write_read(
186 DS3231_ADDR,
187 vec![Register::Control.addr()],
188 vec![0b0010_1010], ),
190 I2cTransaction::write(
192 DS3231_ADDR,
193 vec![Register::Control.addr(), 0b1010_1010 | EOSC_BIT], ),
195 ];
196
197 let mut i2c_mock = I2cMock::new(&expectations);
198 let mut ds3231 = Ds3231::new(&mut i2c_mock);
199
200 let result = ds3231.halt_clock();
201 assert!(result.is_ok());
202
203 i2c_mock.done();
204 }
205
206 #[test]
207 fn test_start_clock_i2c_read_error() {
208 let expectations = vec![
209 I2cTransaction::write_read(DS3231_ADDR, vec![Register::Control.addr()], vec![0x00])
210 .with_error(embedded_hal::i2c::ErrorKind::Other),
211 ];
212
213 let mut i2c_mock = I2cMock::new(&expectations);
214 let mut ds3231 = Ds3231::new(&mut i2c_mock);
215
216 let result = ds3231.start_clock();
217 assert!(result.is_err());
218
219 i2c_mock.done();
220 }
221
222 #[test]
223 fn test_start_clock_i2c_write_error() {
224 let expectations = vec![
225 I2cTransaction::write_read(
226 DS3231_ADDR,
227 vec![Register::Control.addr()],
228 vec![EOSC_BIT], ),
230 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0000_0000])
231 .with_error(embedded_hal::i2c::ErrorKind::Other),
232 ];
233
234 let mut i2c_mock = I2cMock::new(&expectations);
235 let mut ds3231 = Ds3231::new(&mut i2c_mock);
236
237 let result = ds3231.start_clock();
238 assert!(result.is_err());
239
240 i2c_mock.done();
241 }
242
243 #[test]
244 fn test_halt_clock_i2c_read_error() {
245 let expectations = vec![
246 I2cTransaction::write_read(DS3231_ADDR, vec![Register::Control.addr()], vec![0x00])
247 .with_error(embedded_hal::i2c::ErrorKind::Other),
248 ];
249
250 let mut i2c_mock = I2cMock::new(&expectations);
251 let mut ds3231 = Ds3231::new(&mut i2c_mock);
252
253 let result = ds3231.halt_clock();
254 assert!(result.is_err());
255
256 i2c_mock.done();
257 }
258
259 #[test]
260 fn test_halt_clock_i2c_write_error() {
261 let expectations = vec![
262 I2cTransaction::write_read(
263 DS3231_ADDR,
264 vec![Register::Control.addr()],
265 vec![0b0000_0000], ),
267 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), EOSC_BIT])
268 .with_error(embedded_hal::i2c::ErrorKind::Other),
269 ];
270
271 let mut i2c_mock = I2cMock::new(&expectations);
272 let mut ds3231 = Ds3231::new(&mut i2c_mock);
273
274 let result = ds3231.halt_clock();
275 assert!(result.is_err());
276
277 i2c_mock.done();
278 }
279
280 #[test]
281 fn test_power_control_sequence_start_halt_start() {
282 let expectations = vec![
283 I2cTransaction::write_read(DS3231_ADDR, vec![Register::Control.addr()], vec![EOSC_BIT]),
285 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0000_0000]),
286 I2cTransaction::write_read(
288 DS3231_ADDR,
289 vec![Register::Control.addr()],
290 vec![0b0000_0000],
291 ),
292 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), EOSC_BIT]),
293 I2cTransaction::write_read(DS3231_ADDR, vec![Register::Control.addr()], vec![EOSC_BIT]),
295 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0000_0000]),
296 ];
297
298 let mut i2c_mock = I2cMock::new(&expectations);
299 let mut ds3231 = Ds3231::new(&mut i2c_mock);
300
301 assert!(ds3231.start_clock().is_ok());
303 assert!(ds3231.halt_clock().is_ok());
304 assert!(ds3231.start_clock().is_ok());
305
306 i2c_mock.done();
307 }
308
309 #[test]
310 fn test_start_clock_clears_only_eosc_bit() {
311 let expectations = vec![
313 I2cTransaction::write_read(
314 DS3231_ADDR,
315 vec![Register::Control.addr()],
316 vec![0b1111_1111], ),
318 I2cTransaction::write(
319 DS3231_ADDR,
320 vec![Register::Control.addr(), !EOSC_BIT], ),
322 ];
323
324 let mut i2c_mock = I2cMock::new(&expectations);
325 let mut ds3231 = Ds3231::new(&mut i2c_mock);
326
327 let result = ds3231.start_clock();
328 assert!(result.is_ok());
329
330 i2c_mock.done();
331 }
332}