rtc_hal/rtc.rs
1//! # RTC Trait Interface
2//!
3//! This module defines the core trait for Real-Time Clock (RTC) devices in embedded systems.
4//!
5//! ## Features
6//! - Provides a platform-independent interface for reading and writing date/time values to hardware RTC chips.
7//! - Compatible with the design patterns of `embedded-hal`, focusing on trait-based abstraction.
8//! - Uses the hardware-agnostic `DateTime` struct for representing calendar date and time.
9//!
10//! ## Usage Notes
11//! - Each RTC driver should implement its own error type conforming to the `Error` trait, allowing accurate hardware-specific error reporting.
12//! - Drivers are responsible for validating that all `DateTime` values provided are within the supported range of their underlying hardware (for example, some chips only support years 2000-2099).
13//! - This trait is intended for use in platform implementors and applications needing unified RTC access across hardware targets.
14//!
15//! ## For driver authors
16//!
17//! Drivers should take the `Rtc` instance as an argument to `new()`, and store it in their
18//! struct. They **should not** take `&mut Rtc`, the trait has a blanket impl for all `&mut T`
19//! so taking just `Rtc` ensures the user can still pass a `&mut`, but is not forced to.
20//!
21//! Drivers **should not** try to enable sharing by taking `&mut Rtc` at every method.
22//! This is much less ergonomic than owning the `Rtc`, which still allows the user to pass an
23//! implementation that does sharing behind the scenes.
24//!
25//! ## Example
26//! ```ignore
27//! use crate::{datetime::DateTime, error::ErrorType, rtc::Rtc};
28//!
29//! let mut rtc = Ds1307::new(i2c);
30//! let now = rtc.get_datetime()?;
31//! rtc.set_datetime(&DateTime::new(2024, 8, 16, 12, 0, 0)?)?;
32//! ```
33use crate::{datetime::DateTime, error::ErrorType};
34
35/// Core trait for Real-Time Clock (RTC) devices.
36///
37/// This trait provides a platform-agnostic interface for reading and
38/// writing date/time values from hardware RTC chips. It is designed
39/// to be similar in style to `embedded-hal` traits.
40///
41/// Each RTC implementation should define:
42/// - An associated error type for hardware-specific errors
43///
44/// The `DateTime` struct used here is hardware-agnostic. Drivers must
45/// validate that provided values fall within the supported range.
46///
47/// # Example
48///
49/// ```ignore
50/// let mut rtc = Ds1307::new(i2c);
51/// let now = rtc.get_datetime()?;
52/// rtc.set_datetime(&DateTime::new(2024, 8, 16, 12, 0, 0)?)?;
53pub trait Rtc: ErrorType {
54 /// Get the current date and time atomically.
55 ///
56 /// # Errors
57 ///
58 /// Returns `Self::Error` if communication with the RTC fails.
59 fn get_datetime(&mut self) -> Result<DateTime, Self::Error>;
60
61 /// Set the current date and time atomically.
62 ///
63 /// # Errors
64 ///
65 /// Returns `Self::Error` if communication with the RTC fails or
66 /// if the provided `DateTime` is out of range for this device.
67 fn set_datetime(&mut self, datetime: &DateTime) -> Result<(), Self::Error>;
68}
69
70/// blanket impl for all `&mut T`
71impl<T: Rtc + ?Sized> Rtc for &mut T {
72 #[inline]
73 fn get_datetime(&mut self) -> Result<DateTime, Self::Error> {
74 T::get_datetime(self)
75 }
76
77 #[inline]
78 fn set_datetime(&mut self, datetime: &DateTime) -> Result<(), Self::Error> {
79 T::set_datetime(self, datetime)
80 }
81}