1pub use rtc_hal::square_wave::SquareWave;
14pub use rtc_hal::square_wave::SquareWaveFreq;
15
16use crate::Ds3231;
17use crate::error::Error;
18use crate::registers::{INTCN_BIT, RS_MASK, Register};
19
20fn freq_to_bits<E>(freq: SquareWaveFreq) -> Result<u8, Error<E>>
24where
25 E: core::fmt::Debug,
26{
27 match freq {
28 SquareWaveFreq::Hz1 => Ok(0b0000_0000),
29 SquareWaveFreq::Hz1024 => Ok(0b0000_1000),
30 SquareWaveFreq::Hz4096 => Ok(0b0001_0000),
31 SquareWaveFreq::Hz8192 => Ok(0b0001_1000),
32 _ => Err(Error::UnsupportedSqwFrequency),
33 }
34}
35
36impl<I2C> SquareWave for Ds3231<I2C>
37where
38 I2C: embedded_hal::i2c::I2c,
39{
40 fn enable_square_wave(&mut self) -> Result<(), Self::Error> {
42 self.clear_register_bits(Register::Control, INTCN_BIT)
44 }
45
46 fn disable_square_wave(&mut self) -> Result<(), Self::Error> {
48 self.set_register_bits(Register::Control, INTCN_BIT)
50 }
51
52 fn set_square_wave_frequency(&mut self, freq: SquareWaveFreq) -> Result<(), Self::Error> {
53 let rs_bits = freq_to_bits(freq)?;
55
56 let current = self.read_register(Register::Control)?;
58 let mut new_value = current;
59
60 new_value &= !RS_MASK;
62 new_value |= rs_bits; if new_value != current {
66 self.write_register(Register::Control, new_value)
67 } else {
68 Ok(())
69 }
70 }
71
72 fn start_square_wave(&mut self, freq: SquareWaveFreq) -> Result<(), Self::Error> {
73 let rs_bits = freq_to_bits(freq)?;
74 let current = self.read_register(Register::Control)?;
75 let mut new_value = current;
76
77 new_value &= !RS_MASK;
79 new_value |= rs_bits;
80
81 new_value &= !INTCN_BIT;
83
84 if new_value != current {
86 self.write_register(Register::Control, new_value)
87 } else {
88 Ok(())
89 }
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96 use embedded_hal_mock::eh1::i2c::{Mock as I2cMock, Transaction as I2cTransaction};
97 use rtc_hal::square_wave::{SquareWave, SquareWaveFreq};
98
99 const DS3231_ADDR: u8 = 0x68;
100
101 #[test]
102 fn test_freq_to_bits_supported_frequencies() {
103 assert_eq!(
104 freq_to_bits::<()>(SquareWaveFreq::Hz1).unwrap(),
105 0b0000_0000
106 );
107 assert_eq!(
108 freq_to_bits::<()>(SquareWaveFreq::Hz1024).unwrap(),
109 0b0000_1000
110 );
111 assert_eq!(
112 freq_to_bits::<()>(SquareWaveFreq::Hz4096).unwrap(),
113 0b0001_0000
114 );
115 assert_eq!(
116 freq_to_bits::<()>(SquareWaveFreq::Hz8192).unwrap(),
117 0b0001_1000
118 );
119 }
120
121 #[test]
122 fn test_freq_to_bits_unsupported_frequency() {
123 let result = freq_to_bits::<()>(SquareWaveFreq::Hz32768);
124 assert!(matches!(result, Err(Error::UnsupportedSqwFrequency)));
125 }
126
127 #[test]
128 fn test_enable_square_wave() {
129 let expectations = vec![
130 I2cTransaction::write_read(
132 DS3231_ADDR,
133 vec![Register::Control.addr()],
134 vec![0b0000_0100],
135 ),
136 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0000_0000]),
138 ];
139
140 let mut i2c_mock = I2cMock::new(&expectations);
141 let mut ds3231 = Ds3231::new(&mut i2c_mock);
142
143 let result = ds3231.enable_square_wave();
144 assert!(result.is_ok());
145
146 i2c_mock.done();
147 }
148
149 #[test]
150 fn test_enable_square_wave_already_enabled() {
151 let expectations = vec![I2cTransaction::write_read(
152 DS3231_ADDR,
153 vec![Register::Control.addr()],
154 vec![0b0000_0000],
155 )];
156
157 let mut i2c_mock = I2cMock::new(&expectations);
158 let mut ds3231 = Ds3231::new(&mut i2c_mock);
159
160 let result = ds3231.enable_square_wave();
161 assert!(result.is_ok());
162
163 i2c_mock.done();
164 }
165
166 #[test]
167 fn test_disable_square_wave() {
168 let expectations = vec![
169 I2cTransaction::write_read(
170 DS3231_ADDR,
171 vec![Register::Control.addr()],
172 vec![0b0000_0000],
173 ),
174 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0000_0100]),
175 ];
176
177 let mut i2c_mock = I2cMock::new(&expectations);
178 let mut ds3231 = Ds3231::new(&mut i2c_mock);
179
180 let result = ds3231.disable_square_wave();
181 assert!(result.is_ok());
182
183 i2c_mock.done();
184 }
185
186 #[test]
187 fn test_set_square_wave_frequency_1hz() {
188 let expectations = vec![
189 I2cTransaction::write_read(
190 DS3231_ADDR,
191 vec![Register::Control.addr()],
192 vec![0b0001_1000],
193 ),
194 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0000_0000]),
195 ];
196
197 let mut i2c_mock = I2cMock::new(&expectations);
198 let mut ds3231 = Ds3231::new(&mut i2c_mock);
199
200 let result = ds3231.set_square_wave_frequency(SquareWaveFreq::Hz1);
201 assert!(result.is_ok());
202
203 i2c_mock.done();
204 }
205
206 #[test]
207 fn test_set_square_wave_frequency_1024hz() {
208 let expectations = vec![
209 I2cTransaction::write_read(
210 DS3231_ADDR,
211 vec![Register::Control.addr()],
212 vec![0b0000_0000],
213 ),
214 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0000_1000]),
215 ];
216
217 let mut i2c_mock = I2cMock::new(&expectations);
218 let mut ds3231 = Ds3231::new(&mut i2c_mock);
219
220 let result = ds3231.set_square_wave_frequency(SquareWaveFreq::Hz1024);
221 assert!(result.is_ok());
222
223 i2c_mock.done();
224 }
225
226 #[test]
227 fn test_set_square_wave_frequency_4096hz() {
228 let expectations = vec![
229 I2cTransaction::write_read(
230 DS3231_ADDR,
231 vec![Register::Control.addr()],
232 vec![0b0000_1000],
233 ),
234 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0001_0000]),
235 ];
236
237 let mut i2c_mock = I2cMock::new(&expectations);
238 let mut ds3231 = Ds3231::new(&mut i2c_mock);
239
240 let result = ds3231.set_square_wave_frequency(SquareWaveFreq::Hz4096);
241 assert!(result.is_ok());
242
243 i2c_mock.done();
244 }
245
246 #[test]
247 fn test_set_square_wave_frequency_8192hz() {
248 let expectations = vec![
249 I2cTransaction::write_read(
250 DS3231_ADDR,
251 vec![Register::Control.addr()],
252 vec![0b0000_0000],
253 ),
254 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0001_1000]),
255 ];
256
257 let mut i2c_mock = I2cMock::new(&expectations);
258 let mut ds3231 = Ds3231::new(&mut i2c_mock);
259
260 let result = ds3231.set_square_wave_frequency(SquareWaveFreq::Hz8192);
261 assert!(result.is_ok());
262
263 i2c_mock.done();
264 }
265
266 #[test]
267 fn test_set_square_wave_frequency_no_change_needed() {
268 let expectations = vec![I2cTransaction::write_read(
269 DS3231_ADDR,
270 vec![Register::Control.addr()],
271 vec![0b0001_0000], )];
273
274 let mut i2c_mock = I2cMock::new(&expectations);
275 let mut ds3231 = Ds3231::new(&mut i2c_mock);
276
277 let result = ds3231.set_square_wave_frequency(SquareWaveFreq::Hz4096);
278 assert!(result.is_ok());
279
280 i2c_mock.done();
281 }
282
283 #[test]
284 fn test_set_square_wave_frequency_preserves_other_bits() {
285 let expectations = vec![
286 I2cTransaction::write_read(
287 DS3231_ADDR,
288 vec![Register::Control.addr()],
289 vec![0b1100_0100],
290 ),
291 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b1100_1100]),
292 ];
293
294 let mut i2c_mock = I2cMock::new(&expectations);
295 let mut ds3231 = Ds3231::new(&mut i2c_mock);
296
297 let result = ds3231.set_square_wave_frequency(SquareWaveFreq::Hz1024);
298 assert!(result.is_ok());
299
300 i2c_mock.done();
301 }
302
303 #[test]
304 fn test_set_square_wave_frequency_unsupported() {
305 let expectations = vec![];
306
307 let mut i2c_mock = I2cMock::new(&expectations);
308 let mut ds3231 = Ds3231::new(&mut i2c_mock);
309
310 let result = ds3231.set_square_wave_frequency(SquareWaveFreq::Hz32768);
311 assert!(matches!(result, Err(Error::UnsupportedSqwFrequency)));
312
313 i2c_mock.done();
314 }
315
316 #[test]
317 fn test_start_square_wave_1hz() {
318 let expectations = vec![
319 I2cTransaction::write_read(
320 DS3231_ADDR,
321 vec![Register::Control.addr()],
322 vec![0b0001_1100],
323 ),
324 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0000_0000]),
327 ];
328
329 let mut i2c_mock = I2cMock::new(&expectations);
330 let mut ds3231 = Ds3231::new(&mut i2c_mock);
331
332 let result = ds3231.start_square_wave(SquareWaveFreq::Hz1);
333 assert!(result.is_ok());
334
335 i2c_mock.done();
336 }
337
338 #[test]
339 fn test_start_square_wave_1024hz() {
340 let expectations = vec![
341 I2cTransaction::write_read(
342 DS3231_ADDR,
343 vec![Register::Control.addr()],
344 vec![0b1000_0100],
345 ),
346 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b1000_1000]),
347 ];
348
349 let mut i2c_mock = I2cMock::new(&expectations);
350 let mut ds3231 = Ds3231::new(&mut i2c_mock);
351
352 let result = ds3231.start_square_wave(SquareWaveFreq::Hz1024);
353 assert!(result.is_ok());
354
355 i2c_mock.done();
356 }
357
358 #[test]
359 fn test_start_square_wave_4096hz() {
360 let expectations = vec![
361 I2cTransaction::write_read(
362 DS3231_ADDR,
363 vec![Register::Control.addr()],
364 vec![0b0100_1100],
365 ),
366 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0101_0000]),
367 ];
368
369 let mut i2c_mock = I2cMock::new(&expectations);
370 let mut ds3231 = Ds3231::new(&mut i2c_mock);
371
372 let result = ds3231.start_square_wave(SquareWaveFreq::Hz4096);
373 assert!(result.is_ok());
374
375 i2c_mock.done();
376 }
377
378 #[test]
379 fn test_start_square_wave_8192hz() {
380 let expectations = vec![
381 I2cTransaction::write_read(
382 DS3231_ADDR,
383 vec![Register::Control.addr()],
384 vec![0b0000_0100],
385 ),
386 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0001_1000]),
387 ];
388
389 let mut i2c_mock = I2cMock::new(&expectations);
390 let mut ds3231 = Ds3231::new(&mut i2c_mock);
391
392 let result = ds3231.start_square_wave(SquareWaveFreq::Hz8192);
393 assert!(result.is_ok());
394
395 i2c_mock.done();
396 }
397
398 #[test]
399 fn test_start_square_wave_already_configured() {
400 let expectations = vec![I2cTransaction::write_read(
401 DS3231_ADDR,
402 vec![Register::Control.addr()],
403 vec![0b0000_1000],
404 )];
405
406 let mut i2c_mock = I2cMock::new(&expectations);
407 let mut ds3231 = Ds3231::new(&mut i2c_mock);
408
409 let result = ds3231.start_square_wave(SquareWaveFreq::Hz1024);
410 assert!(result.is_ok());
411
412 i2c_mock.done();
413 }
414
415 #[test]
416 fn test_start_square_wave_preserves_other_bits() {
417 let expectations = vec![
418 I2cTransaction::write_read(
419 DS3231_ADDR,
420 vec![Register::Control.addr()],
421 vec![0b1010_0100],
422 ),
423 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b1010_0000]),
424 ];
425
426 let mut i2c_mock = I2cMock::new(&expectations);
427 let mut ds3231 = Ds3231::new(&mut i2c_mock);
428
429 let result = ds3231.start_square_wave(SquareWaveFreq::Hz1);
430 assert!(result.is_ok());
431
432 i2c_mock.done();
433 }
434
435 #[test]
436 fn test_start_square_wave_unsupported_frequency() {
437 let expectations = vec![];
438
439 let mut i2c_mock = I2cMock::new(&expectations);
440 let mut ds3231 = Ds3231::new(&mut i2c_mock);
441
442 let result = ds3231.start_square_wave(SquareWaveFreq::Hz32768);
443 assert!(matches!(result, Err(Error::UnsupportedSqwFrequency)));
444
445 i2c_mock.done();
446 }
447
448 #[test]
449 fn test_i2c_read_error_handling() {
450 let expectations = vec![
451 I2cTransaction::write_read(DS3231_ADDR, vec![Register::Control.addr()], vec![0x00])
452 .with_error(embedded_hal::i2c::ErrorKind::Other),
453 ];
454
455 let mut i2c_mock = I2cMock::new(&expectations);
456 let mut ds3231 = Ds3231::new(&mut i2c_mock);
457
458 let result = ds3231.enable_square_wave();
459 assert!(result.is_err());
460
461 i2c_mock.done();
462 }
463
464 #[test]
465 fn test_i2c_write_error_handling() {
466 let expectations = vec![
467 I2cTransaction::write_read(
468 DS3231_ADDR,
469 vec![Register::Control.addr()],
470 vec![0b0000_0100],
471 ),
472 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0000_0000])
473 .with_error(embedded_hal::i2c::ErrorKind::Other),
474 ];
475
476 let mut i2c_mock = I2cMock::new(&expectations);
477 let mut ds3231 = Ds3231::new(&mut i2c_mock);
478
479 let result = ds3231.enable_square_wave();
480 assert!(result.is_err());
481
482 i2c_mock.done();
483 }
484
485 #[test]
486 fn test_rs_mask_coverage() {
487 let expectations = vec![
488 I2cTransaction::write_read(
489 DS3231_ADDR,
490 vec![Register::Control.addr()],
491 vec![0b1111_1111],
492 ),
493 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b1110_1111]),
494 ];
495
496 let mut i2c_mock = I2cMock::new(&expectations);
497 let mut ds3231 = Ds3231::new(&mut i2c_mock);
498
499 let result = ds3231.set_square_wave_frequency(SquareWaveFreq::Hz1024);
500 assert!(result.is_ok());
501
502 i2c_mock.done();
503 }
504
505 #[test]
506 fn test_intcn_bit_manipulation() {
507 let expectations = vec![
508 I2cTransaction::write_read(
509 DS3231_ADDR,
510 vec![Register::Control.addr()],
511 vec![0b1111_1111],
512 ),
513 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b1111_1011]),
514 ];
515
516 let mut i2c_mock = I2cMock::new(&expectations);
517 let mut ds3231 = Ds3231::new(&mut i2c_mock);
518
519 let result = ds3231.enable_square_wave();
520 assert!(result.is_ok());
521
522 i2c_mock.done();
523 }
524}