1use crate::{interface, BitFlags, Config, Error, Mcp794xx, OutputPinLevel, Register, SqWFreq};
2pub mod alarm;
3pub mod conversion;
4pub mod datetime;
5pub mod sram;
6
7impl Config {
8 pub(crate) fn with_high(self, mask: u8) -> Self {
9 Config {
10 bits: self.bits | mask,
11 }
12 }
13 pub(crate) fn with_low(self, mask: u8) -> Self {
14 Config {
15 bits: self.bits & !mask,
16 }
17 }
18}
19
20impl<DI, E, IC> Mcp794xx<DI, IC>
21where
22 DI: interface::WriteData<Error = Error<E>> + interface::ReadData<Error = Error<E>>,
23{
24 pub fn enable(&mut self) -> Result<(), Error<E>> {
26 let seconds = self.iface.read_register(Register::SECONDS)?;
27 self.iface
28 .write_register(Register::SECONDS, seconds | BitFlags::ST)?;
29 self.is_enabled = true;
30 Ok(())
31 }
32
33 pub fn disable(&mut self) -> Result<(), Error<E>> {
35 let seconds = self.iface.read_register(Register::SECONDS)?;
36 self.iface
37 .write_register(Register::SECONDS, seconds & !BitFlags::ST)?;
38 self.is_enabled = false;
39 Ok(())
40 }
41
42 #[allow(clippy::wrong_self_convention)]
44 pub fn is_oscillator_running(&mut self) -> Result<bool, Error<E>> {
45 let data = self.iface.read_register(Register::WEEKDAY)?;
46 Ok((data & BitFlags::OSCRUN) != 0)
47 }
48
49 pub fn enable_external_oscillator(&mut self) -> Result<(), Error<E>> {
51 self.write_control(self.control.with_high(BitFlags::EXTOSC))
52 }
53
54 pub fn disable_external_oscillator(&mut self) -> Result<(), Error<E>> {
56 self.write_control(self.control.with_low(BitFlags::EXTOSC))
57 }
58
59 pub fn enable_square_wave(&mut self) -> Result<(), Error<E>> {
63 self.write_control(self.control.with_high(BitFlags::SQWEN))
64 }
65
66 pub fn disable_square_wave(&mut self) -> Result<(), Error<E>> {
68 self.write_control(self.control.with_low(BitFlags::SQWEN))
69 }
70
71 pub fn set_square_wave_frequency(&mut self, frequency: SqWFreq) -> Result<(), Error<E>> {
76 let bits = match frequency {
77 SqWFreq::Hz1 => 0,
78 SqWFreq::Hz4_096 => 1,
79 SqWFreq::Hz8_192 => 2,
80 SqWFreq::Hz32_768 => 3,
81 };
82 let control = Config {
83 bits: (self.control.bits & 0b1111_1100) | bits,
84 };
85 self.write_control(control)
86 }
87
88 pub fn set_output_pin(&mut self, level: OutputPinLevel) -> Result<(), Error<E>> {
93 let control = match level {
94 OutputPinLevel::High => self.control.with_high(BitFlags::OUT),
95 OutputPinLevel::Low => self.control.with_low(BitFlags::OUT),
96 };
97 self.write_control(control)
98 }
99
100 pub fn enable_coarse_trim(&mut self) -> Result<(), Error<E>> {
102 self.write_control(self.control.with_high(BitFlags::CRSTRIM))
103 }
104
105 pub fn disable_coarse_trim(&mut self) -> Result<(), Error<E>> {
107 self.write_control(self.control.with_low(BitFlags::CRSTRIM))
108 }
109
110 pub fn set_trimming(&mut self, value: i8) -> Result<(), Error<E>> {
120 if value < 0 && value != -128 {
121 let rest = !(value - 1) as u8;
122 self.iface
123 .write_register(Register::OSCTRIM, 0b1000_0000 | rest)
124 } else {
125 self.iface.write_register(Register::OSCTRIM, value as u8)
126 }
127 }
128
129 fn write_control(&mut self, control: Config) -> Result<(), Error<E>> {
130 self.iface.write_register(Register::CONTROL, control.bits)?;
131 self.control = control;
132 Ok(())
133 }
134
135 #[allow(clippy::needless_pass_by_value)]
136 fn check_lt<T: PartialOrd>(value: T, reference: T) -> Result<(), Error<E>> {
137 if value < reference {
138 Ok(())
139 } else {
140 Err(Error::InvalidInputData)
141 }
142 }
143
144 #[allow(clippy::needless_pass_by_value)]
145 fn check_gt<T: PartialOrd>(value: T, reference: T) -> Result<(), Error<E>> {
146 if value > reference {
147 Ok(())
148 } else {
149 Err(Error::InvalidInputData)
150 }
151 }
152}