1use embedded_hal::i2c::I2c;
4
5use crate::{error::Error, registers::Register};
6
7pub const I2C_ADDR: u8 = 0x68;
9
10pub const DEFAULT_BASE_CENTURY: u8 = 20;
14
15pub struct Ds3231<I2C> {
17 i2c: I2C,
18 pub(crate) base_century: u8,
19}
20
21impl<I2C: embedded_hal::i2c::I2c> rtc_hal::error::ErrorType for Ds3231<I2C> {
22 type Error = crate::error::Error<I2C::Error>;
23}
24
25impl<I2C, E> Ds3231<I2C>
26where
27 I2C: I2c<Error = E>,
28 E: core::fmt::Debug,
29{
30 pub fn new(i2c: I2C) -> Self {
38 Self {
39 i2c,
40 base_century: DEFAULT_BASE_CENTURY,
41 }
42 }
43
44 pub fn set_base_century(&mut self, base_century: u8) -> Result<(), Error<E>> {
67 if base_century < 19 {
68 return Err(Error::InvalidBaseCentury);
69 }
70 self.base_century = base_century;
71 Ok(())
72 }
73
74 pub fn release_i2c(self) -> I2C {
83 self.i2c
84 }
85
86 pub(crate) fn write_register(&mut self, register: Register, value: u8) -> Result<(), Error<E>> {
88 self.i2c.write(I2C_ADDR, &[register.addr(), value])?;
89
90 Ok(())
91 }
92
93 pub(crate) fn read_register(&mut self, register: Register) -> Result<u8, Error<E>> {
95 let mut data = [0u8; 1];
96 self.i2c
97 .write_read(I2C_ADDR, &[register.addr()], &mut data)
98 .map_err(Error::I2c)?;
99
100 Ok(data[0])
101 }
102
103 pub(crate) fn read_register_bytes(
105 &mut self,
106 register: Register,
107 buffer: &mut [u8],
108 ) -> Result<(), Error<E>> {
109 self.i2c.write_read(I2C_ADDR, &[register.addr()], buffer)?;
110
111 Ok(())
112 }
113
114 pub(crate) fn write_raw_bytes(&mut self, data: &[u8]) -> Result<(), Error<E>> {
127 self.i2c.write(I2C_ADDR, data).map_err(Error::I2c)
128 }
129
130 pub(crate) fn set_register_bits(
150 &mut self,
151 register: Register,
152 mask: u8,
153 ) -> Result<(), Error<E>> {
154 let current = self.read_register(register)?;
155 let new_value = current | mask;
156 if new_value != current {
157 self.write_register(register, new_value)
158 } else {
159 Ok(())
160 }
161 }
162
163 pub(crate) fn clear_register_bits(
183 &mut self,
184 register: Register,
185 mask: u8,
186 ) -> Result<(), Error<E>> {
187 let current = self.read_register(register)?;
188 let new_value = current & !mask;
189 if new_value != current {
190 self.write_register(register, new_value)
191 } else {
192 Ok(())
193 }
194 }
195}
196
197#[cfg(test)]
198mod tests {
199 use super::*;
200 use crate::error::Error;
201 use crate::registers::Register;
202 use embedded_hal_mock::eh1::i2c::{Mock as I2cMock, Transaction as I2cTransaction};
203
204 const DS3231_ADDR: u8 = 0x68;
205
206 #[test]
207 fn test_new() {
208 let i2c_mock = I2cMock::new(&[]);
209 let ds3231 = Ds3231::new(i2c_mock);
210
211 assert_eq!(ds3231.base_century, DEFAULT_BASE_CENTURY);
212
213 let mut i2c_mock = ds3231.release_i2c();
214 i2c_mock.done();
215 }
216
217 #[test]
218 fn test_set_base_century_valid() {
219 let i2c_mock = I2cMock::new(&[]);
220 let mut ds3231 = Ds3231::new(i2c_mock);
221
222 let result = ds3231.set_base_century(21);
223 assert!(result.is_ok());
224 assert_eq!(ds3231.base_century, 21);
225
226 let mut i2c_mock = ds3231.release_i2c();
227 i2c_mock.done();
228 }
229
230 #[test]
231 fn test_set_base_century_minimum_valid() {
232 let i2c_mock = I2cMock::new(&[]);
233 let mut ds3231 = Ds3231::new(i2c_mock);
234
235 let result = ds3231.set_base_century(19);
236 assert!(result.is_ok());
237 assert_eq!(ds3231.base_century, 19);
238
239 let mut i2c_mock = ds3231.release_i2c();
240 i2c_mock.done();
241 }
242
243 #[test]
244 fn test_set_base_century_invalid() {
245 let i2c_mock = I2cMock::new(&[]);
246 let mut ds3231 = Ds3231::new(i2c_mock);
247
248 let result = ds3231.set_base_century(18);
249 assert!(matches!(result, Err(Error::InvalidBaseCentury)));
250 assert_eq!(ds3231.base_century, DEFAULT_BASE_CENTURY);
251
252 let mut i2c_mock = ds3231.release_i2c();
253 i2c_mock.done();
254 }
255
256 #[test]
257 fn test_write_register() {
258 let expectations = vec![I2cTransaction::write(
259 DS3231_ADDR,
260 vec![Register::Control.addr(), 0x42],
261 )];
262
263 let i2c_mock = I2cMock::new(&expectations);
264 let mut ds3231 = Ds3231::new(i2c_mock);
265
266 let result = ds3231.write_register(Register::Control, 0x42);
267 assert!(result.is_ok());
268
269 let mut i2c_mock = ds3231.release_i2c();
270 i2c_mock.done();
271 }
272
273 #[test]
274 fn test_write_register_error() {
275 let expectations = vec![
276 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0x42])
277 .with_error(embedded_hal::i2c::ErrorKind::Other),
278 ];
279
280 let i2c_mock = I2cMock::new(&expectations);
281 let mut ds3231 = Ds3231::new(i2c_mock);
282
283 let result = ds3231.write_register(Register::Control, 0x42);
284 assert!(result.is_err());
285
286 let mut i2c_mock = ds3231.release_i2c();
287 i2c_mock.done();
288 }
289
290 #[test]
291 fn test_read_register() {
292 let expectations = vec![I2cTransaction::write_read(
293 DS3231_ADDR,
294 vec![Register::Control.addr()],
295 vec![0x55],
296 )];
297
298 let i2c_mock = I2cMock::new(&expectations);
299 let mut ds3231 = Ds3231::new(i2c_mock);
300
301 let result = ds3231.read_register(Register::Control);
302 assert_eq!(result.unwrap(), 0x55);
303
304 let mut i2c_mock = ds3231.release_i2c();
305 i2c_mock.done();
306 }
307
308 #[test]
309 fn test_read_register_error() {
310 let expectations = vec![
311 I2cTransaction::write_read(DS3231_ADDR, vec![Register::Control.addr()], vec![0x00])
312 .with_error(embedded_hal::i2c::ErrorKind::Other),
313 ];
314
315 let i2c_mock = I2cMock::new(&expectations);
316 let mut ds3231 = Ds3231::new(i2c_mock);
317
318 let result = ds3231.read_register(Register::Control);
319 assert!(result.is_err());
320
321 let mut i2c_mock = ds3231.release_i2c();
322 i2c_mock.done();
323 }
324
325 #[test]
326 fn test_read_register_bytes() {
327 let expectations = vec![I2cTransaction::write_read(
328 DS3231_ADDR,
329 vec![Register::Seconds.addr()],
330 vec![0x11, 0x22, 0x33],
331 )];
332
333 let i2c_mock = I2cMock::new(&expectations);
334 let mut ds3231 = Ds3231::new(i2c_mock);
335
336 let mut buffer = [0u8; 3];
337 let result = ds3231.read_register_bytes(Register::Seconds, &mut buffer);
338 assert!(result.is_ok());
339 assert_eq!(buffer, [0x11, 0x22, 0x33]);
340
341 let mut i2c_mock = ds3231.release_i2c();
342 i2c_mock.done();
343 }
344
345 #[test]
346 fn test_read_register_bytes_error() {
347 let expectations = vec![
348 I2cTransaction::write_read(
349 DS3231_ADDR,
350 vec![Register::Seconds.addr()],
351 vec![0x00, 0x00],
352 )
353 .with_error(embedded_hal::i2c::ErrorKind::Other),
354 ];
355
356 let i2c_mock = I2cMock::new(&expectations);
357 let mut ds3231 = Ds3231::new(i2c_mock);
358
359 let mut buffer = [0u8; 2];
360 let result = ds3231.read_register_bytes(Register::Seconds, &mut buffer);
361 assert!(result.is_err());
362
363 let mut i2c_mock = ds3231.release_i2c();
364 i2c_mock.done();
365 }
366
367 #[test]
368 fn test_write_raw_bytes() {
369 let expectations = vec![I2cTransaction::write(DS3231_ADDR, vec![0x0E, 0x1C, 0x00])];
370
371 let i2c_mock = I2cMock::new(&expectations);
372 let mut ds3231 = Ds3231::new(i2c_mock);
373
374 let result = ds3231.write_raw_bytes(&[0x0E, 0x1C, 0x00]);
375 assert!(result.is_ok());
376
377 let mut i2c_mock = ds3231.release_i2c();
378 i2c_mock.done();
379 }
380
381 #[test]
382 fn test_write_raw_bytes_error() {
383 let expectations = vec![
384 I2cTransaction::write(DS3231_ADDR, vec![0x0E, 0x1C])
385 .with_error(embedded_hal::i2c::ErrorKind::Other),
386 ];
387
388 let i2c_mock = I2cMock::new(&expectations);
389 let mut ds3231 = Ds3231::new(i2c_mock);
390
391 let result = ds3231.write_raw_bytes(&[0x0E, 0x1C]);
392 assert!(result.is_err());
393
394 let mut i2c_mock = ds3231.release_i2c();
395 i2c_mock.done();
396 }
397
398 #[test]
399 fn test_set_register_bits_change_needed() {
400 let expectations = vec![
401 I2cTransaction::write_read(
402 DS3231_ADDR,
403 vec![Register::Control.addr()],
404 vec![0b0000_1000],
405 ),
406 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0001_1000]),
407 ];
408
409 let i2c_mock = I2cMock::new(&expectations);
410 let mut ds3231 = Ds3231::new(i2c_mock);
411
412 let result = ds3231.set_register_bits(Register::Control, 0b0001_0000);
413 assert!(result.is_ok());
414
415 let mut i2c_mock = ds3231.release_i2c();
416 i2c_mock.done();
417 }
418
419 #[test]
420 fn test_set_register_bits_no_change_needed() {
421 let expectations = vec![I2cTransaction::write_read(
422 DS3231_ADDR,
423 vec![Register::Control.addr()],
424 vec![0b0001_1000],
425 )];
426
427 let i2c_mock = I2cMock::new(&expectations);
428 let mut ds3231 = Ds3231::new(i2c_mock);
429
430 let result = ds3231.set_register_bits(Register::Control, 0b0001_0000);
431 assert!(result.is_ok());
432
433 let mut i2c_mock = ds3231.release_i2c();
434 i2c_mock.done();
435 }
436
437 #[test]
438 fn test_set_register_bits_multiple_bits() {
439 let expectations = vec![
440 I2cTransaction::write_read(
441 DS3231_ADDR,
442 vec![Register::Control.addr()],
443 vec![0b0000_0000],
444 ),
445 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b1010_0101]),
446 ];
447
448 let i2c_mock = I2cMock::new(&expectations);
449 let mut ds3231 = Ds3231::new(i2c_mock);
450
451 let result = ds3231.set_register_bits(Register::Control, 0b1010_0101);
452 assert!(result.is_ok());
453
454 let mut i2c_mock = ds3231.release_i2c();
455 i2c_mock.done();
456 }
457
458 #[test]
459 fn test_set_register_bits_read_error() {
460 let expectations = vec![
461 I2cTransaction::write_read(DS3231_ADDR, vec![Register::Control.addr()], vec![0x00])
462 .with_error(embedded_hal::i2c::ErrorKind::Other),
463 ];
464
465 let i2c_mock = I2cMock::new(&expectations);
466 let mut ds3231 = Ds3231::new(i2c_mock);
467
468 let result = ds3231.set_register_bits(Register::Control, 0b0001_0000);
469 assert!(result.is_err());
470
471 let mut i2c_mock = ds3231.release_i2c();
472 i2c_mock.done();
473 }
474
475 #[test]
476 fn test_set_register_bits_write_error() {
477 let expectations = vec![
478 I2cTransaction::write_read(
479 DS3231_ADDR,
480 vec![Register::Control.addr()],
481 vec![0b0000_0000],
482 ),
483 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0001_0000])
484 .with_error(embedded_hal::i2c::ErrorKind::Other),
485 ];
486
487 let i2c_mock = I2cMock::new(&expectations);
488 let mut ds3231 = Ds3231::new(i2c_mock);
489
490 let result = ds3231.set_register_bits(Register::Control, 0b0001_0000);
491 assert!(result.is_err());
492
493 let mut i2c_mock = ds3231.release_i2c();
494 i2c_mock.done();
495 }
496
497 #[test]
498 fn test_clear_register_bits_change_needed() {
499 let expectations = vec![
500 I2cTransaction::write_read(
501 DS3231_ADDR,
502 vec![Register::Control.addr()],
503 vec![0b1111_1111],
504 ),
505 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b1110_1111]),
506 ];
507
508 let i2c_mock = I2cMock::new(&expectations);
509 let mut ds3231 = Ds3231::new(i2c_mock);
510
511 let result = ds3231.clear_register_bits(Register::Control, 0b0001_0000);
512 assert!(result.is_ok());
513
514 let mut i2c_mock = ds3231.release_i2c();
515 i2c_mock.done();
516 }
517
518 #[test]
519 fn test_clear_register_bits_no_change_needed() {
520 let expectations = vec![I2cTransaction::write_read(
521 DS3231_ADDR,
522 vec![Register::Control.addr()],
523 vec![0b1110_1111],
524 )];
525
526 let i2c_mock = I2cMock::new(&expectations);
527 let mut ds3231 = Ds3231::new(i2c_mock);
528
529 let result = ds3231.clear_register_bits(Register::Control, 0b0001_0000);
530 assert!(result.is_ok());
531
532 let mut i2c_mock = ds3231.release_i2c();
533 i2c_mock.done();
534 }
535
536 #[test]
537 fn test_clear_register_bits_multiple_bits() {
538 let expectations = vec![
539 I2cTransaction::write_read(
540 DS3231_ADDR,
541 vec![Register::Control.addr()],
542 vec![0b1111_1111],
543 ),
544 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0101_1010]),
545 ];
546
547 let i2c_mock = I2cMock::new(&expectations);
548 let mut ds3231 = Ds3231::new(i2c_mock);
549
550 let result = ds3231.clear_register_bits(Register::Control, 0b1010_0101);
551 assert!(result.is_ok());
552
553 let mut i2c_mock = ds3231.release_i2c();
554 i2c_mock.done();
555 }
556
557 #[test]
558 fn test_clear_register_bits_read_error() {
559 let expectations = vec![
560 I2cTransaction::write_read(DS3231_ADDR, vec![Register::Control.addr()], vec![0x00])
561 .with_error(embedded_hal::i2c::ErrorKind::Other),
562 ];
563
564 let i2c_mock = I2cMock::new(&expectations);
565 let mut ds3231 = Ds3231::new(i2c_mock);
566
567 let result = ds3231.clear_register_bits(Register::Control, 0b0001_0000);
568 assert!(result.is_err());
569
570 let mut i2c_mock = ds3231.release_i2c();
571 i2c_mock.done();
572 }
573
574 #[test]
575 fn test_clear_register_bits_write_error() {
576 let expectations = vec![
577 I2cTransaction::write_read(
578 DS3231_ADDR,
579 vec![Register::Control.addr()],
580 vec![0b1111_1111],
581 ),
582 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b1110_1111])
583 .with_error(embedded_hal::i2c::ErrorKind::Other),
584 ];
585
586 let i2c_mock = I2cMock::new(&expectations);
587 let mut ds3231 = Ds3231::new(i2c_mock);
588
589 let result = ds3231.clear_register_bits(Register::Control, 0b0001_0000);
590 assert!(result.is_err());
591
592 let mut i2c_mock = ds3231.release_i2c();
593 i2c_mock.done();
594 }
595
596 #[test]
597 fn test_constants() {
598 assert_eq!(I2C_ADDR, 0x68);
599 assert_eq!(DEFAULT_BASE_CENTURY, 20);
600 }
601
602 #[test]
603 fn test_set_register_bits_preserves_other_bits() {
604 let expectations = vec![
605 I2cTransaction::write_read(
606 DS3231_ADDR,
607 vec![Register::Control.addr()],
608 vec![0b1000_0010],
609 ),
610 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b1001_0010]),
611 ];
612
613 let i2c_mock = I2cMock::new(&expectations);
614 let mut ds3231 = Ds3231::new(i2c_mock);
615
616 let result = ds3231.set_register_bits(Register::Control, 0b0001_0000);
617 assert!(result.is_ok());
618
619 let mut i2c_mock = ds3231.release_i2c();
620 i2c_mock.done();
621 }
622
623 #[test]
624 fn test_clear_register_bits_preserves_other_bits() {
625 let expectations = vec![
626 I2cTransaction::write_read(
627 DS3231_ADDR,
628 vec![Register::Control.addr()],
629 vec![0b1001_0010],
630 ),
631 I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b1000_0010]),
632 ];
633
634 let i2c_mock = I2cMock::new(&expectations);
635 let mut ds3231 = Ds3231::new(i2c_mock);
636
637 let result = ds3231.clear_register_bits(Register::Control, 0b0001_0000);
638 assert!(result.is_ok());
639
640 let mut i2c_mock = ds3231.release_i2c();
641 i2c_mock.done();
642 }
643}